將多行同群組的某欄位值串聯成單一字串 (如部門員工姓名清單),Oracle 提供 WM_CONCAT (非官方、12c 移除) 與 LISTAGG (11gR2+ 官方標準) 兩種函數。本文提供建表測試資料、兩函數語法對比、結果展示、版本相容性與最佳實踐建議。
CREATE TABLE mytest (
xtype NUMBER,
city NVARCHAR2(200)
);
INSERT INTO mytest VALUES (1, N'北京');
INSERT INTO mytest VALUES (1, N'上海');
INSERT INTO mytest VALUES (1, N'廣州');
INSERT INTO mytest VALUES (2, N'武漢');
INSERT INTO mytest VALUES (2, N'杭州');
INSERT INTO mytest VALUES (2, N'廈門');
COMMIT;
SELECT xtype,
wmsys.wm_concat(TO_CHAR(city)) AS xcity
FROM mytest
GROUP BY xtype;
WMSYS Schema,官方文檔**未公開**,屬內部工具函數。SELECT xtype,
LISTAGG(TO_CHAR(city), ',') WITHIN GROUP (ORDER BY xtype) AS xcity
FROM mytest
GROUP BY xtype;
LISTAGG(expr, delimiter) WITHIN GROUP (ORDER BY sort_expr)WITHIN GROUP (ORDER BY ...) 控制串聯順序。ON OVERFLOW TRUNCATE '...' WITH COUNT 避免超過 4000/32767 字元報錯 (VARCHAR2/CLOB)。LISTAGG(...) OVER (PARTITION BY deptno)。XTYPE XCITY
----- ------------------------------
1 北京,廣州,上海
2 杭州,武漢,廈門
註:WM_CONCAT 不保證順序;LISTAGG 依 ORDER BY xtype 排序 (同群組內 xtype 相同,實際順序非確定,建議 ORDER BY city 或具體業務欄位)。
| 特性 | WM_CONCAT | LISTAGG |
|---|---|---|
| 官方支援 | 否 (非文檔化) | 是 (11gR2+) |
| 12c 可用性 | 已移除 | 完全支援 |
| 分隔符 | 固定逗號 | 可自訂 |
| 排序控制 | 無 | WITHIN GROUP (ORDER BY) |
| 溢位處理 | 無 (靜默截斷/報錯) | 12cR2+ ON OVERFLOW TRUNCATE |
| 分析函數 | 否 | 是 (OVER 子句) |
| 回傳型別 | VARCHAR2 (4000) | VARCHAR2 (4000) / CLOB (12c+) |
TO_CHAR(city) 確保字元集一致,避免隱含轉換亂碼。XMLAGG(XMLELEMENT(e, city || ',').EXTRACT('//text()')).GETCLOBVAL() 回傳 CLOB。LISTAGG(city, ',') ON OVERFLOW TRUNCATE '...' WITH COUNT 或回傳 CLOB (隱含)。WHERE 過濾、並確保群組欄位有索引支援 SORT GROUP BY。