LISTAGG(name, ',')

  • 作用LISTAGG 是 Oracle 提供的一個聚合函數(從 Oracle 11gR2 開始支持),用於將多行的某個字段值連接成一個字符串。
  • 參數説明
  • name:要聚合的列名,即你想把哪些值拼接起來。
  • ',':分隔符,這裏用英文逗號 , 分隔各個值。

例如,如果 name 的值是 'A', 'B', 'C',那麼 LISTAGG(name, ',') 會生成 'A,B,C'

⚠️ 注意:單獨使用 LISTAGG(...) 是不合法的,必須配合 WITHIN GROUP (ORDER BY ...) 子句。


2. WITHIN GROUP (ORDER BY id)

  • 作用:指定在拼接字符串時,各值的排列順序。
  • 説明
  • ORDER BY id 表示按照 id 列的升序(默認)對 name 進行排序後再拼接。
  • WITHIN GROUP 是 LISTAGG 語法的一部分,不能省略。

例如,假設有以下數據:

那麼 LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) 的結果是 'A,B,C'

id

name

3

C

1

A

2

B


3. CAST(... AS VARCHAR2(4000))

  • 作用:顯式地將 LISTAGG 返回的結果轉換為 VARCHAR2(4000) 類型。
  • 為什麼需要?
  • 在 Oracle 中,LISTAGG 函數默認返回的是 VARCHAR2 類型,但其最大長度受 MAX_STRING_SIZE 參數影響:
  • 如果數據庫是 標準模式(Standard),最大長度為 4000 字節
  • 如果啓用了 擴展數據類型(Extended Data Types)MAX_STRING_SIZE = EXTENDED),則 VARCHAR2 最大可達 32767 字節
  • 然而,在某些上下文中(比如創建視圖、插入到特定列、或與其他類型交互時),Oracle 可能無法自動推斷或限制返回長度,導致潛在的 ORA-01489: 字符串連接結果太長 錯誤。
  • 使用 CAST(... AS VARCHAR2(4000)) 明確限制結果長度為 4000 字節,可以:
  • 避免類型歧義;
  • 確保與目標列(如 VARCHAR2(4000))兼容;
  • 在某些版本中,幫助優化器更好地處理執行計劃。

⚠️ 注意:如果拼接後的字符串實際長度超過 4000 字節,即使你寫了 CAST AS VARCHAR2(4000)仍然會報 ORA-01489 錯誤CAST 不會截斷數據,它只是聲明類型。真正限制長度的是 LISTAGG 本身的實現限制。


補充:如何處理超長問題?

從 Oracle 12cR2 開始,可以使用 ON OVERFLOW TRUNCATE 選項來避免錯誤:

LISTAGG(name, ',' ON OVERFLOW TRUNCATE '...' WITH COUNT) 
  WITHIN GROUP (ORDER BY id)

這會在結果超過上限時自動截斷並添加提示(如 ...),避免報錯。


總結

部分

説明

LISTAGG(name, ',')

將 name 列的值用逗號連接

WITHIN GROUP (ORDER BY id)

按照 id 排序後再連接

CAST(... AS VARCHAR2(4000))

顯式指定結果為 VARCHAR2(4000) 類型,增強兼容性和明確性

典型使用場景
在一個分組查詢中(如 GROUP BY some_col),將每個分組內的多個標籤(name)合併成一個字符串字段。

例如:

SELECT 
  category,
  CAST(LISTAGG(name, ',') WITHIN GROUP (ORDER BY id) AS VARCHAR2(4000)) AS tags
FROM my_table
GROUP BY category;