根据日期在SQL Server中合并和合并行

时间:2018-08-24 13:06:20

标签: sql-server consolidation

我有一个包含数十亿条记录的表,其中包含以下商品信息。 ID为bigint,具有自动递增功能。文章中的UPC和MRP是实际数据。 DataDate拥有该MRP的适用日期等信息。

ID        Article            EANUPC         MRP        DataDate        
8546417   20171554001        1220636        599        20/11/2015        
18589213  20171554001        1220636        599        15/12/2017        
18655485  20171554001        1220636        390        26/12/2017        
18784953  20171554001        1220636        390        11/1/2018        
18833697  20171554001        1220636        290        16/1/2018        
18954190  20171554001        1220636        290        24/1/2018        
19060047  20171554001        1220636        190        30/1/2018        
19116702  20171554001        1220636        90        6/2/2018        
20107113  20171554001        1220636        90        13/6/2018        
20143100  20171554001        1220636        599        13/6/2018

我希望以这样的方式合并记录:如果后续几天的MRP相同。那么它应该显示该MRP的有效起始日期和有效截止日期。

我需要以下输出。

Article            EANUPC        MRP        FromDate        ToDate
20171554001        1220636        599        20/11/2015     25/12/2017
20171554001        1220636        390        26/12/2017     15/01/2018
20171554001        1220636        290        16/1/2018      29/01/2018
20171554001        1220636        190        30/1/2018      05/02/2018
20171554001        1220636        90         6/2/2018       12/06/2018
20171554001        1220636        599        13/6/2018      24/08/2018

请帮助我实现这一目标。

2 个答案:

答案 0 :(得分:0)

您正在寻找GROUP BY

SELECT
    Article
    , EANUPC
    , MRP
    , MIN(DataDate) as FromDate
    , MAX(DataDate) as ToDate
FROM
    [Your_Table]
GROUP BY
    Article, EANUPC, MRP

您将需要创建一个新表并将这些记录插入到其中,但是它应该可以工作。另外,如果它有数十亿条记录,则您很可能希望分批处理它,以免它使您的服务器瘫痪。

答案 1 :(得分:0)

您可以将其视为间隙和孤岛问题。使用:

SELECT Article, EANUPC, MRP, DataDate,
       ROW_NUMBER() OVER (PARTITION BY Article ORDER BY DataDate) -
       ROW_NUMBER() OVER (PARTITION BY Article, MRP ORDER BY DataDate) AS grp
FROM mytable
ORDER BY DataDate

您得到:

Article     EANUPC  MRP DataDate    grp
---------------------------------------
20171554001 1220636 599 2015-11-20  0
20171554001 1220636 599 2017-12-15  0
20171554001 1220636 390 2017-12-26  2
20171554001 1220636 390 2018-01-11  2
20171554001 1220636 290 2018-01-16  4
20171554001 1220636 290 2018-01-24  4
20171554001 1220636 190 2018-01-30  6
20171554001 1220636 90  2018-02-06  7
20171554001 1220636 90  2018-06-13  7
20171554001 1220636 599 2018-06-13  7

您现在可以将以上查询包装在CTE中,并使用grp字段进行分组:

;WITH CTE AS (
    SELECT Article, EANUPC, MRP, DataDate,
           ROW_NUMBER() OVER (PARTITION BY Article ORDER BY DataDate) -
           ROW_NUMBER() OVER (PARTITION BY Article, MRP ORDER BY DataDate) AS grp
    FROM mytable
)
SELECT Article, EANUPC, MRP, MIN(DataDate) AS FromDate
FROM CTE 
GROUP BY Article, EANUPC, MRP, grp 

输出:

Article     EANUPC  MRP FromDate
----------------------------------
20171554001 1220636 599 2015-11-20
20171554001 1220636 390 2017-12-26
20171554001 1220636 290 2018-01-16
20171554001 1220636 190 2018-01-30
20171554001 1220636 90  2018-02-06
20171554001 1220636 599 2018-06-13

您可以使用LEAD获得最终结果:

;WITH CTE AS (
    SELECT Article, EANUPC, MRP, DataDate,
           ROW_NUMBER() OVER (PARTITION BY Article ORDER BY DataDate) -
           ROW_NUMBER() OVER (PARTITION BY Article, MRP ORDER BY DataDate) AS grp
    FROM mytable
), CTE2 AS (
    SELECT Article, EANUPC, MRP, MIN(DataDate) AS FromDate
    FROM CTE 
    GROUP BY Article, EANUPC, MRP,grp  
)
SELECT Article, EANUPC, MRP, FromDate, 
       COALESCE(DATEADD(day, -1, LEAD(FromDate) OVER (ORDER BY FromDate)), FromDate) AS ToDate
FROM CTE2

输出:

Article     EANUPC  MRP FromDate    ToDate
----------------------------------------------
20171554001 1220636 599 2015-11-20  2017-12-25
20171554001 1220636 390 2017-12-26  2018-01-15
20171554001 1220636 290 2018-01-16  2018-01-29
20171554001 1220636 190 2018-01-30  2018-02-05
20171554001 1220636 90  2018-02-06  2018-06-12
20171554001 1220636 599 2018-06-13  2018-06-13