要實現的是去重按順序分組拼接字段,且輸出表中需要拼接多個字段。
1、查了網上大概有四種方法,各有特點:
1、wmsys.wm_concat(column)
2、listagg (column,[,]) within group (order by ) [over (partition by )]
3、sys_connect_by_path(column,<分隔符>)
4、xmlagg (content column,[,] wellformed) within group (order by ) [over (partition by )]
第1種,WMSYS用戶用於Workspace Manager,函數對象可能因版本而不同,Oracle官方也不建議使用;不可指定分隔符;支持去重。
第2種,listagg返回結果varchar2類型(最大長度4000),當拼接字符串過長會提示“返回結果為字符串連接的結果過長”;可指定分隔符;不支持去重。
第3種,此方法未測試。
第4種,返回結果為clob(Character Large Object)類型,最大容量為4GB;可指定分隔符;不支持去重。
2、確定了使用第4種方法,發現實現難點在於分組結果去重,又存在多個字段需要拼接,則先去重只可針對一個字段,多個字段就存在問題,采用先產生針對不同字段拼接的臨時表,使用分組字段作為連接更新到主表中。
網上針對xmlagg可使用的去重方法有兩種,一種是使用正則表達式(適用於字符串大小比較小的情況,不適用),另一種是先去重再聚合。
CREATE Global Temporary TABLE D302_2 ON COMMIT PRESERVE ROWS AS
SELECT SHENG,
XIAN,
XMMC,
BHYY,
BHSD,
SYLDXZ,
rtrim(xmlagg(xmlparse(content PAN_NO_TB || '、' wellformed) ORDER BY PAN_NO_TB).getclobval(),
'、') AS PAN_NO_TB
FROM (SELECT DISTINCT SHENG, XIAN, XMMC, BHYY, BHSD, SYLDXZ, PAN_NO_TB
FROM TEST
WHERE PAN_NO_TB <> 0)
GROUP BY SHENG, XIAN, XMMC, BHYY, BHSD, SYLDXZ;
from 后面括號內實現去重目的
group by 實現分組目的
xmlagg(xmlparse(content PAN_NO_TB || '、' wellformed) ORDER BY PAN_NO_TB) 實現拼接
getclobval() 獲得clob字符串
rtrim 去除最后面的 "、"
注意:xmlagg字段若為字符串,需適應to_char()函數轉換。
3、使用分組字段作為連接更新到主表中(a2,a3,a7,a8,a9,a10分別為主表的SHENG, XIAN, XMMC, BHYY, BHSD, SYLDXZ)
UPDATE D302_1
SET D302_1.a5 =
(SELECT PAN_NO_TB
FROM D302_3
WHERE D302_3.sheng = D302_1.A2
AND D302_3.XIAN = D302_1.A3
AND D302_3.XMMC = D302_1.A7
AND D302_3.BHYY = D302_1.A8
AND D302_3.BHSD = D302_1.A9
AND D302_3.SYLDXZ = D302_1.A10)
WHERE EXISTS (SELECT PAN_NO_TB
FROM D302_3
WHERE D302_3.sheng = D302_1.A2
AND D302_3.XIAN = D302_1.A3
AND D302_3.XMMC = D302_1.A7
AND D302_3.BHYY = D302_1.A8
AND D302_3.BHSD = D302_1.A9
AND D302_3.SYLDXZ = D302_1.A10);
WHERE EXISTS避免不匹配項被更新為空值。
