SQL Server:按月汇总,有差距

时间:2018-01-03 16:34:31

标签: sql sql-server sql-server-2008 sequence gaps-and-islands

我需要一些帮助来汇总一些数据。想象一下,我有下表:

            Employee    Reference Period
            123440      20141201
            123440      20150101
            123440      20150201
            123440      20150301
            123440      20160201
            123440      20160301
            123440      20160401
            123440      20160501
            123440      20160601
            123440      20160701
            123440      20160801
            123440      20160901
            123440      20161001
            123442      20141201
            123442      20150101
            123442      20150201
            123442      20150301
            123442      20150401
            123442      20150501
            123442      20150601
            123442      20150701
            123442      20150801
            123442      20150901
            123442      20151001
            123442      20151101
            123442      20151201
            123442      20170301
            123442      20170401
            123442      20170501
            123442      20170601
            123442      20170701
            123442      20170801
            123442      20170901
            123442      20171001
            123442      20171101
            123442      20171201

我需要一个SQL查询来输出以下内容:

Employee    From_Date   To_Date
123440      20141201    20150301
123440      20160201    20161001
123442      20141201    20151201
123442      20170301    20171201

基本上我需要的是加入没有月份间隔的行,并在序列中返回[From Date] MIN(),并在序列中返回[To Date] MIN()。有人可以帮帮我吗?

我尝试执行以下查询:

;WITH CTE
     AS (SELECT [Employee], t1refer, t2refer, DIFF,
                Grp2 = ROW_NUMBER()OVER(partition BY [Employee],DIFF ORDER BY t1refer),
                Grp = ROW_NUMBER()OVER(partition BY [Employee],DIFF ORDER BY t1refer) - DIFF
          FROM (
            SELECT DISTINCT t1.[Employee], t1.[Reference Period] t1refer , t2.[Reference Period] t2refer, DATEDIFF(MONTH, CONVERT(DATE,CONVERT(VARCHAR(10),(t2.[Reference Period]+'01'),101)),CONVERT(DATE,CONVERT(VARCHAR(10),(t1.[Reference Period]+'01'),101))) AS DIFF
            FROM MyTable t1 
                CROSS APPLY 
                (SELECT TOP 1 t.[Reference Period] FROM MyTable t 
                    WHERE t.[Employee] = t1.[Employee] AND CONVERT(date,CONVERT(VARCHAR(10),(t.[Reference Period]+'01'),101)) < CONVERT(date,CONVERT(VARCHAR(10),(t1.[Reference Period]+'01'),101)) ORDER BY t.[Reference Period] DESC) t2
            ) QRY
            )
        SELECT [Employee],
       [From Date] = MIN(t2refer),
       [To Date] = MAX(t1refer)     
         FROM CTE   
         GROUP BY [Employee], DIFF 

请注意,该数据库是SQL Server 2008.

1 个答案:

答案 0 :(得分:2)

另一个经典的差距和岛屿问题

;WITH cte
     AS (SELECT a.*,
                Prev_period = b.[Reference Period]
         FROM   Yourtable a
                LEFT JOIN Yourtable b
                       ON a.Employee = b.Employee
                          AND Dateadd(mm, 1, b.[Reference Period]) = a.[Reference Period])
SELECT Employee,
       From_Date = Min([Reference Period]),
       To_Date = Max([Reference Period])
FROM   cte a
       CROSS apply(SELECT Sum(CASE WHEN [Reference Period] = Dateadd(mm, 1, Prev_period) THEN 0 ELSE 1 END)
                   FROM   cte b
                   WHERE  a.Employee = b.Employee
                          AND a.[Reference Period] >= b.[Reference Period]) cs (grp)
GROUP  BY Employee,
          grp