使用SQL 15.0.2000.5版

我有一个表格,里面有这些数据:

StudentScheduleId Monday Tuesday Wednesday Thursday Friday MondayStartTime MondayEndTime TuesdayStartTime TuesdayEndTime WednesdayStartTime WednesdayEndTime ThursdayStartTime ThursdayEndTime FridayStartTime FridayEndTime
15 1 1 1 1 NULL 9:00 11:00 11:00 12:30 9:00 11:00 11:00 12:30 NULL NULL
31 1 NULL NULL 1 0 2:00 3:15 NULL NULL NULL NULL 2:00 3:15 NULL NULL

我想实现这样的格式:

StudentScheduleId Schedule StartTime EndTime
15 T/Th 11:00 12:30
15 M/W 9:00 11:00
31 M 9:00 11:00

我可以使用这个查询来做到这一点:

Select s.StudentScheduleId, 
    STRING_AGG(s.[Day], '/') AS Schedule, 
    s.StartTime, 
    s.EndTime
From
(
(Select s.StudentScheduleId, 'M' As [Day], s.MondayStartTime As StartTime, s.MondayEndTime As EndTime
From StudentSchedule s
Where s.Monday = 1)
UNION
(Select s.StudentScheduleId, 'T' As [Day], s.TuesDayStartTime As StartTime, s.TuesdayEndTime As EndTime
From StudentSchedule s
Where s.Tuesday = 1)
UNION
(Select s.StudentScheduleId, 'W' As [Day], s.WednesdayStartTime As StartTime, s.WednesdayEndTime As EndTime
From StudentSchedule s
Where s.Wednesday = 1)
UNION
(Select s.StudentScheduleId, 'Th' As [Day], s.ThursdayStartTime As StartTime, s.ThursdayEndTime As EndTime
From StudentSchedule s
Where s.Thursday = 1)
UNION
(Select s.StudentScheduleId, 'F' As [Day], s.FridayStartTime As StartTime, s.FridayEndTime As EndTime
From StudentSchedule s
Where s.Friday = 1)
) As s
Group By s.StudentScheduleId, s.StartTime, s.EndTime

然而,我对结果有一个担忧,也有一个问题.

  1. 有没有更好更熟练的方法来做到这一点考虑到性能或只是更简洁? 我不指望这个表会有数百万条记录,但我可以看到它最终会增长到100万条.
  2. 我测试了其他场景,使用一周中的更多天,具有相同的开始和结束时间,并且日程列结果可以以任何顺序出现. (例如:F/M/T/Th/W). 我希望这是以逻辑顺序M/T/W/Th/F出来的. 我知道strING_AGG的PROCEIN GROUP排序,但没有什么可排序的,或者我需要添加一个排序列,有什么 idea 吗?

谢谢你的帮助!

推荐答案

一个简短的解决方案:

SELECT  *
INTO #data
FROM    (
    VALUES  (15, 1, 1, 1, 1, NULL, N'9:00', N'11:00', N'11:00', N'12:30', N'9:00', N'11:00', N'11:00', N'12:30', cast(NULL AS nvarchar(10)), cast(NULL AS nvarchar(10)))
    ,   (31, 1, NULL, NULL, 1, 0, N'2:00', N'3:15', NULL, NULL, NULL, NULL, N'2:00', N'3:15', NULL, NULL)
) t (StudentScheduleId,Monday,Tuesday,Wednesday,Thursday,Friday,MondayStartTime,MondayEndTime,TuesdayStartTime,TuesdayEndTime,WednesdayStartTime,WednesdayEndTime,ThursdayStartTime,ThursdayEndTime,FridayStartTime,FridayEndTime)

SELECT  StudentScheduleId, starttime, endtime, STRING_AGG(shortcode, '/') WITHIN GROUP (ORDER BY daynumber)
FROM    #data d
CROSS APPLY (
    VALUES  (1,'M',monday, mondaystarttime, mondayendtime)
    ,   (2,'T',tuesday, tuesdaystarttime, tuesdayendtime)
    ,   (3,'W',Wednesday, WednesdayStartTime, WednesdayEndTime)
    ,   (4,'Th',Thursday, ThursdayStartTime, ThursdayEndTime)
    ,   (5,'F',Friday, FridayStartTime, FridayEndTime)
    ) v (daynumber, shortcode, day, starttime, endtime)
WHERE   v.day = 1
GROUP BY starttime, endtime,StudentScheduleId
ORDER BY StudentScheduleId, MIN(daynumber)

您可以将日期和时间分解为行,这大大简化了聚合.

Sql相关问答推荐

如何转换和汇总行数

仅 for each 唯一ID返回一个元素,并仅返回最新连接的记录

当一个视图在Postgres中失效时?

判断序列索引处的序列是否完整

数据库SQL-CTE命名空间(错误?)使用临时视图

如何将不同层次的产品组和规格组合到最深一层?

Postgres SQL查询从字符串中获取邮箱地址

VS代码无法识别SQL代码中带括号的字符串

存储过程太慢

在同一列上迭代时计算持续时间

Clickhouse:左连接表到外部数组

如何在 SQL 中将两行(或多行)jsonb 数组合并为一行

每次计数器增加时通过运行总重置进行分组

JSON对象查询SQL服务器

查询中获取审批者不起作用

根据行号将列转置为没有任何id或键列的行

忽略与给定列匹配的行的 LAG 函数

超过100名员工的连续行

并非所有变量都绑定在 PL SQL 函数中

如何使用子查询锁定此查询中的选定行?