如何用GROUP BY为多职级用户拼接职级?SQL结果合并求助
解决方案:合并同一员工的多个角色为逗号分隔字符串
嘿,这个需求很常见——你需要把同一个员工对应的多个职级(Role)合并成逗号分隔的形式,之前用GROUP BY只拿到首个记录是因为没用到字符串聚合函数,不同数据库有对应的函数来实现这个功能,我给你分情况整理了可行的SQL写法:
1. MySQL/MariaDB 版本
使用GROUP_CONCAT()函数来拼接分组内的字符串:
SELECT CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', GROUP_CONCAT(role.Role SEPARATOR ', ') AS 'Roles' FROM jobs INNER JOIN school ON jobs.SchoolID = school.SchoolID INNER JOIN staff ON jobs.StaffID = staff.StaffID INNER JOIN role ON jobs.RoleID = role.RoleID GROUP BY staff.StaffID, staff.First_Name, staff.Last_Name ORDER BY staff.StaffID ASC;
- 说明:
GROUP_CONCAT会自动将分组内的所有Role值用指定分隔符拼接;GROUP BY中包含StaffID是为了唯一区分员工(避免同名情况),同时带上First_Name和Last_Name是为了兼容MySQL的分组规则。
2. SQL Server 2017+/Azure SQL 版本
使用STRING_AGG()函数:
SELECT CONCAT(staff.First_Name, ' ', staff.Last_Name) AS 'Full_Name', STRING_AGG(role.Role, ', ') WITHIN GROUP (ORDER BY role.Role) AS 'Roles' FROM jobs INNER JOIN school ON jobs.SchoolID = school.SchoolID INNER JOIN staff ON jobs.StaffID = staff.StaffID INNER JOIN role ON jobs.RoleID = role.RoleID GROUP BY staff.StaffID, staff.First_Name, staff.Last_Name ORDER BY staff.StaffID ASC;
- 说明:
WITHIN GROUP (ORDER BY role.Role)可以指定拼接后角色的排序顺序,这部分是可选的,如果不需要排序可以去掉。
3. PostgreSQL 版本
同样使用STRING_AGG()函数:
SELECT CONCAT(staff.First_Name, ' ', staff.Last_Name) AS "Full_Name", STRING_AGG(role.Role, ', ') AS "Roles" FROM jobs INNER JOIN school ON jobs.SchoolID = school.SchoolID INNER JOIN staff ON jobs.StaffID = staff.StaffID INNER JOIN role ON jobs.RoleID = role.RoleID GROUP BY staff.StaffID, staff.First_Name, staff.Last_Name ORDER BY staff.StaffID ASC;
- 说明:如果需要对拼接的角色排序,可以修改为
STRING_AGG(role.Role, ', ') ORDER BY role.Role。
4. Oracle 11g+ 版本
使用LISTAGG()函数:
SELECT CONCAT(staff.First_Name, ' ', staff.Last_Name) AS "Full_Name", LISTAGG(role.Role, ', ') WITHIN GROUP (ORDER BY role.Role) AS "Roles" FROM jobs INNER JOIN school ON jobs.SchoolID = school.SchoolID INNER JOIN staff ON jobs.StaffID = staff.StaffID INNER JOIN role ON jobs.RoleID = role.RoleID GROUP BY staff.StaffID, staff.First_Name, staff.Last_Name ORDER BY staff.StaffID ASC;
为什么之前的GROUP BY只拿到首个记录?
你之前的GROUP BY可能只指定了JobID或者仅StaffID但没有对Role进行聚合操作,数据库默认只会返回分组内的第一条Role值。而通过上面的字符串聚合函数,就能把分组内所有的Role值拼接成一个字符串返回。
内容的提问来源于stack exchange,提问作者GoGoAllen
相关产品推荐
相关产品推荐

