【问题标题】:How to get max date of another column in to new column in SQL Query?如何获取另一列的最大日期到 SQL 查询中的新列?
【发布时间】:2018-02-12 11:16:47
【问题描述】:

我有一个包含订单 ID 和日期列的表,我需要将 enddate 列的最大值放入一个新列中。下面的示例

ID  OrderId StartDate   begindate   enddate
1   2345    06/07/2011  20/08/2011  12/07/2012
2   2345    05/07/2012  11/07/2012  13/01/2014
3   2345    21/05/2014  28/10/2013  27/05/2015
4   2345    23/05/2015  03/06/2015  02/06/2017
5   2345    27/03/2017  20/06/2017  NULL

所以我想得到我的输出是:

需要的输出

ID  OrderId StartDate   begindate   enddate      LastEnddate
1   2345    06/07/2011  20/08/2011  12/07/2012     NULL
2   2345    05/07/2012  11/07/2012  13/01/2014     NULL
3   2345    21/05/2014  28/10/2013  27/05/2015      NULL
4   2345    23/05/2015  03/06/2015  **02/06/2017**  NULL
5   2345    27/03/2017  20/06/2017  NULL           **02/06/2017**

最大EndDate 应该在Lastenddate 列中,其中Enddate 为NULL

我已经尝试创建临时表并应用密集排名,但我仍然缺少一些东西,你能帮忙吗?

我正在将来自temptable 的查询写成

SELECT id, orderid
     , CASE WHEN MAX(CASE WHEN Lasttenddate IS NULL THEN 1 ELSE 0 END) = 0 THEN MAX(enddate) END
FROM #Test
WHERE
 orderid = 2345
GROUP BY id, orderid

提前致谢。

【问题讨论】:

    标签: sql sql-server ssis max temp-tables


    【解决方案1】:

    使用 Cte ,使用 Row_numberMax date 使用最大值 rownumber 计算。 日期输出在您所需的string format 中。

    DECLARE @table TABLE (id INT, orderid INT, startdate VARCHAR(100), begindate VARCHAR(100), enddate VARCHAR(100))
    
    INSERT INTO @table (ID, OrderId, StartDate, begindate, enddate)
    SELECT 1, 2345, '06/07/2011', '20/08/2011', '12/07/2012'
    
    UNION ALL
    
    SELECT 2, 2345, '05/07/2012', '11/07/2012', '13/01/2014'
    
    UNION ALL
    
    SELECT 3, 2345, '21/05/2014', '28/10/2013', '27/05/2015'
    
    UNION ALL
    
    SELECT 4, 2345, '23/05/2015', '03/06/2015', '02/06/2017'
    
    UNION ALL
    
    SELECT 5, 2345, '27/03/2017', '20/06/2017', NULL;
    
    WITH DATE
    AS (
        SELECT *, ROW_NUMBER() OVER (
                PARTITION BY orderid ORDER BY enddate DESC
                ) rn
        FROM @table
        WHERE enddate IS NOT NULL
        )
    SELECT t.id, t.orderid, t.startdate, t.enddate, CASE WHEN t.enddate IS NOT NULL THEN NULL ELSE convert(VARCHAR(10), (
                        SELECT max(convert(DATETIME, enddate, 103))
                        FROM DATE
                        ), 103) END DATE
    FROM @table t
    LEFT JOIN DATE d
        ON d.id = t.id
            AND t.orderid = d.orderid
    

    【讨论】:

      【解决方案2】:

      试试这个:

      SELECT id, orderid,enddate, CASE WHEN enddate is null 
      THEN MAX(enddate) over (partition by orderid)  else null END as LastEnddate
      FROM #Test
      WHERE orderid = 2345
      

      输出:

      id  orderid enddate LastEnddate
      1   2345    2012-07-12  NULL
      2   2345    2014-01-13  NULL
      3   2345    2015-05-27  NULL
      4   2345    2017-06-02  NULL
      5   2345    NULL        2017-06-02
      

      【讨论】:

      • 嗨,感谢您的回复,当我使用上述脚本时,我在最后一个 enddate 列中得到 Max(begindate),但我希望输出是 max(enddate)。
      【解决方案3】:

      您可以使用CROSS APPLY 获取MAX(enddate) 并将其与您的查询结合起来,如下所示。如果您愿意,也可以根据数据量使用CASEROW_NUMBER。当每个分区有很多行时,CROSS APPLY 更好。

      SELECT id, 
             orderid, 
             startdate, 
             begindate, 
             enddate, 
             ( CASE 
                 WHEN T.enddate IS NULL THEN TM.md 
                 ELSE NULL 
               END ) AS LastEnddate 
      FROM   @MyTable T 
             CROSS apply (SELECT Max(enddate) MD 
                          FROM   @MyTable WHERE OrderId= T.OrderId) TM 
      WHERE T.orderid=2345
      

      完整示例

      DECLARE @MyTable TABLE 
        ( 
           id        INT, 
           orderid   INT, 
           startdate DATE, 
           begindate DATE, 
           enddate   DATE 
        ) 
      
      INSERT INTO @MyTable 
      SELECT * 
      FROM   (VALUES (1, 
             2345, 
             CONVERT(DATETIME, '06/07/2011', 103), 
             CONVERT(DATETIME, '20/08/2011', 103), 
             CONVERT(DATETIME, '12/07/2012', 103)), 
                     (2, 
             2345, 
             CONVERT(DATETIME, '05/07/2012', 103), 
             CONVERT(DATETIME, '11/07/2012', 103), 
             CONVERT(DATETIME, '13/01/2014', 103)), 
                     (3, 
             2345, 
             CONVERT(DATETIME, '21/05/2014', 103), 
             CONVERT(DATETIME, '28/10/2013', 103), 
             CONVERT(DATETIME, '27/05/2015', 103)), 
                     (4, 
             2345, 
             CONVERT(DATETIME, '23/05/2015', 103), 
             CONVERT(DATETIME, '03/06/2015', 103), 
             CONVERT(DATETIME, '02/06/2017', 103)), 
                     (5, 
             2345, 
             CONVERT(DATETIME, '27/03/2017', 103), 
             CONVERT(DATETIME, '20/06/2017', 103), 
             NULL) ) t (id, orderid, startdate, begindate, enddate) 
      
      SELECT id, 
             orderid, 
             startdate, 
             begindate, 
             enddate, 
             ( CASE 
                 WHEN T.enddate IS NULL THEN TM.md 
                 ELSE NULL 
               END ) AS LastEnddate 
      FROM   @MyTable T 
             CROSS apply (SELECT Max(enddate) MD 
                          FROM   @MyTable WHERE OrderId= T.OrderId) TM 
      WHERE T.orderid=2345
      

      输出

      id  orderid startdate   begindate   enddate LastEnddate
      1   2345    2011-07-06  2011-08-20  2012-07-12  NULL
      2   2345    2012-07-05  2012-07-11  2014-01-13  NULL
      3   2345    2014-05-21  2013-10-28  2015-05-27  NULL
      4   2345    2015-05-23  2015-06-03  2017-06-02  NULL
      5   2345    2017-03-27  2017-06-20  NULL    2017-06-02
      

      【讨论】:

      • 嗨,我试过了,它工作得很好,但我想要的日期是 max(enddate) = 02/06/2017 但我得到的是 2019- 03-31 有点搞不清楚日期,请帮忙
      • 检查我用示例数据更新的示例。您可能还有一些您在问题中没有提到的附加条件。
      • 我已经添加了 orderid 条件,它现在应该可以工作了。
      【解决方案4】:

      除了Anagha的回答 我会使用以下查询(从性能角度)

      SELECT id, orderid,enddate, 
              CASE WHEN enddate IS NULL THEN LAST_VALUE(enddate) OVER (PARTITION BY OrderId ORDER BY enddate ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) END LastEndDate
       FROM #Test
      

      在 Max(enddate) 解决方案中,您将获得比 LAST_VALUE 解决方案更多的逻辑读取

      查看统计结果:

      最大(结束日期)-> 表“工作台”。扫描计数 3,逻辑读取 15,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表“#B131B1E5”。扫描计数 1,逻辑读取 1,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

      LAST_VALUE - > 表“工作台”。扫描计数 0,逻辑读取 0,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。 表“#B131B1E5”。扫描计数 1,逻辑读取 1,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

      * 注意:*此解决方案适用于 SQL Server 2012 及更高版本

      【讨论】:

        猜你喜欢
        • 2021-11-15
        • 2015-02-22
        • 2016-05-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-25
        相关资源
        最近更新 更多