首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 列值合併聚合:WM_CONCAT 與 LISTAGG 完整對比與用法

     編輯:Oracle 資料庫相關知識

將多行同群組的某欄位值串聯成單一字串 (如部門員工姓名清單),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;

二、WM_CONCAT (舊版、非文檔化)

SELECT xtype,
       wmsys.wm_concat(TO_CHAR(city)) AS xcity
FROM mytest
GROUP BY xtype;
  • 隸屬 WMSYS Schema,官方文檔**未公開**,屬內部工具函數。
  • 12c 起**已移除**,升級後將失效。
  • 不支援自訂分隔符 (固定逗號)、不支援排序。
  • 建議:僅用於 11gR1 及以下舊系統維護,新開發**禁用**。

三、LISTAGG (11gR2+ 官方標準,推薦)

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 ...) 控制串聯順序。
  • 12cR2+ 支援 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_CONCATLISTAGG
官方支援否 (非文檔化)是 (11gR2+)
12c 可用性已移除完全支援
分隔符固定逗號可自訂
排序控制無WITHIN GROUP (ORDER BY)
溢位處理無 (靜默截斷/報錯)12cR2+ ON OVERFLOW TRUNCATE
分析函數否是 (OVER 子句)
回傳型別VARCHAR2 (4000)VARCHAR2 (4000) / CLOB (12c+)

六、最佳實踐建議

  1. 新專案全面使用 LISTAGG,棄用 WM_CONCAT。
  2. TO_CHAR(city) 確保字元集一致,避免隱含轉換亂碼。
  3. 大量資料群組串聯可能超過 4000 字元 (VARCHAR2 上限):
    • 11g/12cR1:改用 XMLAGG(XMLELEMENT(e, city || ',').EXTRACT('//text()')).GETCLOBVAL() 回傳 CLOB。
    • 12cR2+:LISTAGG(city, ',') ON OVERFLOW TRUNCATE '...' WITH COUNT 或回傳 CLOB (隱含)。
  4. 效能:大表群組聚合建議先 WHERE 過濾、並確保群組欄位有索引支援 SORT GROUP BY。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved