SQL多行转单行问题:获取课程实际运行日期并排序
问题分析与解决方案
你的SQL出现两个核心问题:返回全周日期、日期未排序,根源在于子查询没有关联外层的当前课程,导致拉取了所有课程的日期数据。下面是针对性的修正方案:
修正后的SQL语句
SELECT dbo.Courses.DisplayName AS CourseInternalName, dbo.Courses.CourseID, STUFF( ( SELECT DISTINCT ',' + CASE CourseSchedules.dayid WHEN 1 THEN 'Mon' WHEN 2 THEN 'Tue' WHEN 3 THEN 'Wed' WHEN 4 THEN 'Thur' WHEN 5 THEN 'Fri' WHEN 6 THEN 'Sat' WHEN 7 THEN 'Sun' END FROM dbo.CourseSchedules -- 关键:绑定外层当前课程的GUID,仅获取该课程的有效日程 WHERE CourseSchedules.CourseGUID = dbo.Courses.CourseGUID -- 按星期顺序排序,保证输出为周一到周日的自然顺序 ORDER BY CASE CourseSchedules.dayid WHEN 1 THEN 1 WHEN 2 THEN 2 WHEN 3 THEN 3 WHEN 4 THEN 4 WHEN 5 THEN 5 WHEN 6 THEN 6 WHEN 7 THEN 7 END FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '' ) AS Days FROM dbo.Courses LEFT OUTER JOIN dbo.CourseSchedules ON dbo.Courses.CourseGUID = dbo.CourseSchedules.CourseGUID WHERE dbo.Courses.CourseID = 5815 GROUP BY dbo.Courses.DisplayName, dbo.Courses.CourseID, dbo.Courses.CourseGUID
关键修改说明
子查询关联外层课程:
原来的子查询重复执行了Courses LEFT JOIN CourseSchedules,但没有绑定到当前查询的课程,导致拉取了所有课程的日期(去重后就是全周)。现在子查询直接从CourseSchedules取数,通过WHERE CourseSchedules.CourseGUID = dbo.Courses.CourseGUID仅获取当前课程的有效日程。添加日期排序逻辑:
在子查询中加入ORDER BY,通过匹配dayid的数字值,确保输出的星期按Mon→Tue→Wed→Thur→Fri→Sat→Sun的顺序排列。优化结果格式与避免重复:
- 外层添加
GROUP BY,合并因LEFT JOIN产生的多行课程记录,最终只返回单行课程数据。 - 使用
FOR XML PATH(''), TYPE配合.value()方法,避免特殊字符被XML转义(比如&不会变成&),保证输出内容的准确性。
- 外层添加
执行后,你会得到该课程实际运行的日期列表,且顺序符合常规星期排序。
内容的提问来源于stack exchange,提问作者sabbegk
相关产品推荐
相关产品推荐

