抱歉标题含糊(我只是不知道如何描述这个难题)
给出下面的教室时间表:
╔═══════════╦════════════╦═══════════╦═══════════╦═════════╗
║ Classroom ║ CourseName ║ Lesson ║ StartTime ║ EndTime ║
╠═══════════╬════════════╬═══════════╬═══════════╬═════════╣
║ 1001 ║ Course 1 ║ Lesson 1 ║ 0800 ║ 0900 ║
║ 1001 ║ Course 1 ║ Lesson 2 ║ 0900 ║ 1000 ║
║ 1001 ║ Course 1 ║ Lesson 3 ║ 1000 ║ 1100 ║
║ 1001 ║ Course 2 ║ Lesson 10 ║ 1100 ║ 1200 ║
║ 1001 ║ Course 2 ║ Lesson 11 ║ 1200 ║ 1300 ║
║ 1001 ║ Course 1 ║ Lesson 4 ║ 1300 ║ 1400 ║
║ 1001 ║ Course 1 ║ Lesson 5 ║ 1400 ║ 1500 ║
╚═══════════╩════════════╩═══════════╩═══════════╩═════════╝
我想对表格进行分组以显示:
╔═══════════╦════════════╦═══════════╦═════════╗
║ Classroom ║ CourseName ║ StartTime ║ EndTime ║
╠═══════════╬════════════╬═══════════╬═════════╣
║ 1001 ║ Course 1 ║ 0800 ║ 1100 ║
║ 1001 ║ Course 2 ║ 1100 ║ 1300 ║
║ 1001 ║ Course 1 ║ 1300 ║ 1500 ║
╚═══════════╩════════════╩═══════════╩═════════╝
基本上,我们正在查看一个时间表,显示在特定时间跨度内哪个 crouse 正在使用哪个教室......
我最初的想法是:
按
Classroom
分组和 CourseName
并采取Max
和 Min
对于 start\end
时间,但这不会给我显示的时间跨度,好像类(class) 1 正在使用 Classroom
08:00 - 16:00 中间不休息。
最佳答案
如果您使用的是 SQLServer 2012 或更高版本,您可以使用 LAG
获取列的前一个值,然后 SUM() OVER (ORDER BY ...)
创建一个滚动总和,在这种情况下计算 CourseName 的变化,可用作 GROUP BY
anchor
With A AS (
SELECT ClassRoom
, CourseName
, StartTime
, EndTime
, PrevCourse = LAG(CourseName, 1, CourseName) OVER (ORDER BY StartTime)
FROM Table1
), B AS (
SELECT ClassRoom
, CourseName
, StartTime
, EndTime
, Ranker = SUM(CASE WHEN CourseName = PrevCourse THEN 0 ELSE 1 END)
OVER (ORDER BY StartTime, CourseName)
FROM A
)
SELECT ClassRoom
, CourseName
, MIN(StartTime) StartTime
, MAX(EndTime) EndTime
FROM B
GROUP BY ClassRoom, CourseName, Ranker
ORDER BY StartTime
SQLFiddle demo
关于sql - 使用时间跨度对具有相同值的连续行进行分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24244659/