如何将SQL查询中同一学生的多个RACECD合并至单行结果?
合并同一学生的多个种族代码(RACECD)到同一行
要解决同一学生多条种族代码拆分多行的问题,核心是用字符串聚合函数把同一学生的所有RACECD合并成一个逗号分隔的字符串,同时按学生维度分组。不同数据库的聚合函数略有差异,以下是主流数据库的实现方案:
通用思路
- 用
INNER JOIN关联两张表(替代原查询的逗号连接写法,更规范) - 按学生的唯一标识及其他需要保留的字段分组
- 用对应数据库的字符串聚合函数合并
RACECD
各数据库实现示例
MySQL/MariaDB
使用GROUP_CONCAT函数:
SELECT s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS, GROUP_CONCAT(sr.RACECD SEPARATOR ',') AS RACECD FROM STUDENTS s INNER JOIN STUDENTRACE sr ON s.ID = sr.STUDENTID WHERE s.ENROLL_STATUS = 0 GROUP BY s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS;
SQL Server/Azure SQL
使用STRING_AGG函数:
SELECT s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS, STRING_AGG(sr.RACECD, ',') AS RACECD FROM STUDENTS s INNER JOIN STUDENTRACE sr ON s.ID = sr.STUDENTID WHERE s.ENROLL_STATUS = 0 GROUP BY s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS;
Oracle
使用LISTAGG函数:
SELECT s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS, LISTAGG(sr.RACECD, ',') WITHIN GROUP (ORDER BY sr.RACECD) AS RACECD FROM STUDENTS s INNER JOIN STUDENTRACE sr ON s.ID = sr.STUDENTID WHERE s.ENROLL_STATUS = 0 GROUP BY s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS;
PostgreSQL
使用STRING_AGG函数:
SELECT s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS, STRING_AGG(sr.RACECD, ',' ORDER BY sr.RACECD) AS RACECD FROM STUDENTS s INNER JOIN STUDENTRACE sr ON s.ID = sr.STUDENTID WHERE s.ENROLL_STATUS = 0 GROUP BY s.ID, s.STUDENT_NUMBER, s.FIRST_NAME, s.LAST_NAME, s.ENROLL_STATUS;
额外说明
GROUP BY子句必须包含所有非聚合字段(也就是学生表中除了RACECD之外的所有选中字段),否则会触发语法错误- 如果同一学生存在重复的
RACECD,可以在聚合函数中加入DISTINCT去重,比如GROUP_CONCAT(DISTINCT sr.RACECD SEPARATOR ',') - 原查询中
STUDENTRACE.STUDENTID和STUDENTS.ID是同一值,无需重复选中,保留s.ID即可
内容的提问来源于stack exchange,提问作者rwood
相关产品推荐
相关产品推荐

