實際報錯的SQL異常復雜,現抽取出來大概是這樣子:
SELECT WMSYS.WM_CONCAT(DISTINCT COMPNAME) FROM
(SELECT * FROM
(SELECT NEWSCODE,COMPCODE FROM T_NEWS_COMPANY_BD) A
INNER JOIN TQ_COMP_INFO C
ON A.COMPCODE = C.COMPCODE) GROUP BY NEWSCODE
由於按NEWSCODE分組后,有部分組中COMPNAME數量過多,導致拼接后大於4000個字符,而ORACLE又太笨,不會直接加省略號忽略后面的結果,而是選擇報錯.
在網上也搜了一些解決方案,要么是自定義聚合函數,要么是用CLOB字段處理,或者再嵌套幾層過濾掉過多的記錄,感覺都太過於復雜,不便迅速解決問題。思考了好久,終於想到使用PARTITION BY來解決這個問題,解決后的SQL如下:
SELECT WMSYS.WM_CONCAT(DISTINCT CASE WHEN RANK < 100 THEN COMPNAME END) FROM
(SELECT * FROM
(SELECT NEWSCODE,COMPCODE,RANK() OVER(PARTITION BY NEWSCODE ORDER BY COMPCODE) RANK FROM T_NEWS_COMPANY_BD) A
INNER JOIN TQ_COMP_INFO C
ON A.COMPCODE = C.COMPCODE) GROUP BY NEWSCODE
這種方法需要修改的SQL代碼量極少,如果不在乎后面省略掉的字段與PARTITION BY所造成的略微的性能損失的話,個人覺得是最佳解決方案。