如何将SQL查询中多行列课程编码合并至同一单元格
解决方案
核心逻辑
将同一学员关联的所有课程编码聚合拼接成字符串,关键是保证表关联的准确性,避免错误关联或重复数据导致的异常问题。
方案1:使用STRING_AGG(SQL Server 2017及以上版本)
这是最简洁的实现方式,直接调用内置聚合函数完成拼接:
SELECT p.PEOPLE_ID, p.NAME, -- 替换为你需要展示的其他学员字段 STRING_AGG(uio.COURSE_CODE, ';') AS 合并课程编码 FROM PEOPLE p LEFT JOIN PEOPLE_UNITS pu ON p.PEOPLE_ID = pu.PEOPLE_ID LEFT JOIN UNIT_INSTANCE_OCCURRENCES uio ON pu.UNIT_INSTANCE_OCCURRENCE_ID = uio.UNIT_INSTANCE_OCCURRENCE_ID GROUP BY p.PEOPLE_ID, p.NAME -- 所有非聚合的学员字段必须加入GROUP BY
方案2:使用STUFF + FOR XML PATH(兼容旧版SQL Server)
如果你的数据库版本不支持STRING_AGG,可以用这个经典写法,注意规避重复和错误关联:
SELECT p.PEOPLE_ID, p.NAME, STUFF( ( SELECT ';' + uio.COURSE_CODE FROM PEOPLE_UNITS pu JOIN UNIT_INSTANCE_OCCURRENCES uio ON pu.UNIT_INSTANCE_OCCURRENCE_ID = uio.UNIT_INSTANCE_OCCURRENCE_ID WHERE pu.PEOPLE_ID = p.PEOPLE_ID FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '' -- 移除开头多余的分号 ) AS 合并课程编码 FROM PEOPLE p GROUP BY p.PEOPLE_ID, p.NAME
常见问题修复
- 出现不存在的课程编码:大概率是表关联条件错误,仔细核对
PEOPLE_UNITS与UNIT_INSTANCE_OCCURRENCES的关联字段,确保只关联对应选课记录的课程详情,避免用错ID字段。 - 返回重复行:要么是
GROUP BY中遗漏了非聚合的学员字段,要么是关联时产生了笛卡尔积。可以通过DISTINCT去重:
或在方案2的子查询中添加-- 方案1中添加DISTINCT STRING_AGG(DISTINCT uio.COURSE_CODE, ';') AS 合并课程编码DISTINCT:SELECT DISTINCT ';' + uio.COURSE_CODE ...
内容的提问来源于stack exchange,提问作者Joe G
相关产品推荐
相关产品推荐

