學生-科目表,一學生多科目,需查詢每生科目列表(逗號分隔):
-- 源數據
stu | sub
張三 | 數學
李四 | 歷史
李四 | 音樂
李四 | 英語
張三 | 音樂
-- 目標結果
stu | sub
張三 | 數學,音樂
李四 | 歷史,音樂,英語
SELECT stu,
STUFF((
SELECT ',' + sub
FROM Students a
WHERE a.stu = b.stu
FOR XML PATH('')
), 1, 1, '') AS sub
FROM Students b
GROUP BY stu;
FOR XML PATH(''):將查詢結果按行拼接為XML片段,無標籤名產生純文本,數學,音樂。STUFF(str, 1, 1, ''):刪除首字符逗號,得到數學,音樂。WHERE a.stu = b.stu確保按學生分組拼接。| 數據庫 | 函數/語法 | 示例 |
|---|---|---|
| MySQL 8.0+ | GROUP_CONCAT | SELECT stu, GROUP_CONCAT(sub) FROM Students GROUP BY stu |
| PostgreSQL | STRING_AGG | SELECT stu, STRING_AGG(sub, ',') FROM Students GROUP BY stu |
| Oracle 11gR2+ | LISTAGG | SELECT stu, LISTAGG(sub, ',') WITHIN GROUP (ORDER BY sub) FROM Students GROUP BY stu |
FOR XML PATH較慢;可考慮CLR聚合函數或應用層拼接。sub字段無NULL,否則導致整行結果為NULL(用ISNULL(sub,'')處理)。