根据日期范围压缩数据

时间:2018-04-01 18:21:33

标签: sql-server common-table-expression

我有以下格式的数据:

Vbeln在日期范围Begda和Endda重复。对于不同的Begda和Endda范围PernrZa和PernrZb的变化(但它可能会在未来的日期范围内返回到先前的状态。日期范围是连续的。

我需要压缩日期范围并构建一个连续的日期范围

CREATE TABLE #Data (
   Vbeln                NVARCHAR(12)
   , Begda           NVARCHAR(10) -- but can be converted to datetime2
   , Endda           NVARCHAR(10) -- but can be converted to datetime2
   , PernrZa          NVARCHAR(10)
   , PernrZb         NVARCHAR(10)
)
INSERT INTO #Data (Vbeln, Begda, Endda, PernrZa, PernrZb)
VALUES
('3000080085','19000101','20160411','1111111','1111111')
,('3000080085','20160412','20160418','1521708','1895971')
,('3000080085','20160419','20160516','1521708','1895971')
,('3000080085','20160517','20160519','1521708','1895971')
,('3000080085','20160520','20160523','1521708','1895971')
,('3000080085','20160524','20160606','1521708','2304882')
,('3000080085','20160607','20160628','1521708','1895971')
,('3000080085','20160629','20160826','1521708','2304882')
,('3000080085','20160827','20160909','1521708','2304882')
,('3000080085','20160910','20161011','1579311','2304882')
,('3000080085','20161012','20161201','1579311','2889814')
,('3000080085','20161202','20161225','1579311','2889814')
,('3000080085','20161226','99991231','1111111','1111111')
,('2000094798','19000101','20121029','1315393','1315393')
,('2000094798','20121030','20121224','1315393','1315393')
,('2000094798','20121225','20130331','1315393','1315393')
,('2000094798','20130401','20131003','1315393','1315393')
,('2000094798','20131004','20140429','1315393','1315393')
,('2000094798','20140430','20150326','1315393','1315393')
,('2000094798','20150327','20160826','1315393','1315393')
,('2000094798','20160827','20160909','1315393','1315393')
,('2000094798','20160910','20161201','1315393','1315393')
,('2000094798','20161202','99991231','1315393','1315393')

我想要输出如下:

'3000080085','19000101','20160412','1111111','1111111'
'3000080085','20160412','20160524','1521708','1895971'
'3000080085','20160524','20160607','1521708','2304882'
'3000080085','20160607','20160629','1521708','1895971'
'3000080085','20160629','20160910','1521708','2304882'
'3000080085','20160910','20161012','1579311','2304882'
'3000080085','20161012','20161226','1579311','2889814'
'3000080085','20161226','99991231','1111111','1111111'
'2000094798','19000101','99991231','1315393','1315393'

1 个答案:

答案 0 :(得分:0)

您可以使用lag()识别群组:

select vbeln, PernrZa, PernrZb, min(begda), max(endda)
from (select d.*,
             sum(case when prev_enda = dateadd(day, -1, begda) then 0 else 1 end) over
                 (partition by vbeln, PernrZa, PernrZb order by begda) as grp
      from (select d.*,
                   lag(endda) over (partition by vbeln, PernrZa, PernrZb order by begda) as prev_enda             
            from #data d
           ) d
     ) d
group by vbeln, PernrZa, PernrZb, grp;

请注意,这将提前一天提供enda - 因为这是原始数据的结构。如果您真的愿意,可以在结束日期添加一个。

Here是rextester。