如何用SQL Server 2012查询日期表并生成指定汇总格式结果?
解决SQL Server 2012中连续日期分组聚合问题
针对你提到的StayDateInfo表数据,我们需要将同一ResaID下连续使用同一种RoomCat的记录合并,生成包含起止日期和住宿时长的结果。这是一个经典的连续序列分组场景,在SQL Server 2012中可以通过窗口函数轻松实现。
解决方案代码
WITH CTE_Grouped AS ( SELECT ResaID, RoomCat, StayDate, -- 生成分组标识:连续日期减去组内序号后会得到相同值 DATEADD(DAY, -ROW_NUMBER() OVER(PARTITION BY ResaID, RoomCat ORDER BY StayDate), StayDate) AS GroupID FROM StayDateInfo ) SELECT ResaID, RoomCat, MIN(StayDate) AS StartDate, MAX(StayDate) AS EndDate, DATEDIFF(DAY, MIN(StayDate), MAX(StayDate)) + 1 AS Length FROM CTE_Grouped GROUP BY ResaID, RoomCat, GroupID ORDER BY ResaID, StartDate;
代码解释
CTE分组准备:
- 使用
ROW_NUMBER()窗口函数,按ResaID和RoomCat分区(即同一个预订同一种房型为一组),再按StayDate升序排序,给每组内的记录分配序号。 - 通过
DATEADD(DAY, -序号, StayDate)计算GroupID:连续的日期减去对应的序号后,会得到一个固定的日期值,这样就能把连续入住的记录归为同一个分组。
- 使用
聚合生成结果:
- 按
ResaID、RoomCat和GroupID分组,取每组中最小的StayDate作为入住开始日期,最大的作为结束日期。 - 住宿时长
Length用DATEDIFF(DAY, 开始日期, 结束日期) + 1计算,因为DATEDIFF只算间隔天数,需要加1来包含起止当天。
- 按
测试结果
针对你提供的示例数据,执行上述代码后会得到完全符合要求的输出:
| ResaID | RoomCat | StartDate | EndDate | Length |
|---|---|---|---|---|
| 100 | STD | 2018-03-01 | 2018-03-02 | 2 |
| 150 | STD | 2018-04-10 | 2018-04-12 | 3 |
| 150 | DLX | 2018-04-13 | 2018-04-13 | 1 |
内容的提问来源于stack exchange,提问作者user3115933
相关产品推荐
相关产品推荐

