SQL Server:按月汇总,有间隔
Posted
技术标签:
【中文标题】SQL Server:按月汇总,有间隔【英文标题】:SQL Server : aggregate by month with gaps 【发布时间】:2018-01-03 16:34:30 【问题描述】:我需要一些帮助来汇总一些数据。想象一下,我有下表:
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】:另一个经典的差距和孤岛问题
;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
Demo
【讨论】:
这个答案已被标记为已接受,但我确信这似乎只是因为 OP 示例数据中的巧合。这确实是一个间隙和孤岛问题,但DENSE_RANK
需要替换为将月份转换为整数的东西,每月步进为 1(这样不连续性会显示在纯连续的 ROW_NUMBER
上)。它还需要按照与ROW_NUMBER
相同的方式按员工进行分区。
@Steve - 更新...立即查看以上是关于SQL Server:按月汇总,有间隔的主要内容,如果未能解决你的问题,请参考以下文章