? 本文記錄一下Oracle列轉(zhuǎn)行函數(shù)在Oracle11的一些不兼容問題,vm_concat在一些業(yè)務(wù)場(chǎng)景是必須的。不過這個(gè)函數(shù)使用要謹(jǐn)慎,底層實(shí)現(xiàn)應(yīng)該也是group by等等實(shí)現(xiàn)的,性能并不是特別好。這個(gè)函數(shù)在Oracle12C是沒有的,在Oracle11是不太兼容的,Oracle10可以正常使用。最近開發(fā)場(chǎng)景遇到這個(gè)問題,可以寫到了自定義列轉(zhuǎn)行函數(shù)的辦法去解決。但是這種辦法并不一定適用所有的業(yè)務(wù)場(chǎng)景。
建網(wǎng)站原本是網(wǎng)站策劃師、網(wǎng)絡(luò)程序員、網(wǎng)頁設(shè)計(jì)師等,應(yīng)用各種網(wǎng)絡(luò)程序開發(fā)技術(shù)和網(wǎng)頁設(shè)計(jì)技術(shù)配合操作的協(xié)同工作。成都創(chuàng)新互聯(lián)專業(yè)提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站制作(企業(yè)站、響應(yīng)式網(wǎng)站開發(fā)、電商門戶網(wǎng)站)等服務(wù),從網(wǎng)站深度策劃、搜索引擎友好度優(yōu)化到用戶體驗(yàn)的提升,我們力求做到極致!
解決方案
? ? 通過自定義函數(shù)解決也是可以的,不過我并不是這樣做的。 下面介紹一下我的解決方法。首先分析一下,Oracle19C不兼容vm_concat列轉(zhuǎn)行函數(shù),并不代表其它函數(shù)不兼容,或許可以找到其它代替的,通過找資料,發(fā)現(xiàn)了Oracle11提供的另外一個(gè)函數(shù):listagg()函數(shù) 語法:listagg(參數(shù),‘分隔符’) within group(order by 參數(shù)id),驗(yàn)證可以實(shí)現(xiàn)在19C正常使用
例如:
to_char(wm_concat(t.busi_id))
可以改寫成:
to_char(listagg(t.busi_id,',' ) within GROUP (order by (t.busi_id)))
SQL如:
SELECT listagg(t.busi_id, ',') within GROUP(order by (t.busi_id))
FROM sys_cdc_sync_record t
WHERE cdc_sql_type = 'INSERT_SELECT'
固定列數(shù)的行列轉(zhuǎn)換如
student subject grade
---------------------------
student1 語文 80
student1 數(shù)學(xué) 70
student1 英語 60
student2 語文 90
student2 數(shù)學(xué) 80
student2 英語 100
轉(zhuǎn)換為
語文 數(shù)學(xué) 英語
student1 80 70 60
student2 90 80 100
語句如下:
select student,sum(decode(subject,'語文', grade,null)) "語文",
sum(decode(subject,'數(shù)學(xué)', grade,null)) "數(shù)學(xué)",
sum(decode(subject,'英語', grade,null)) "英語"
from table
group by student
2、不定列行列轉(zhuǎn)換如
c1 c2
--------------
1 我
1 是
1 誰
2 知
2 道
3 不
......
轉(zhuǎn)換為
1 我是誰
2 知道
3 不
這一類型的轉(zhuǎn)換必須借助于PL/SQL來完成,這里給一個(gè)例子
CREATE OR REPLACE FUNCTION get_c2(tmp_c1 NUMBER)
RETURN VARCHAR2
IS
--用于返回值
Col_c2 VARCHAR2(4000);
BEGIN
FOR cur IN (SELECT c2 FROM t WHERE c1=tmp_c1) LOOP
Col_c2 := Col_c2||cur.c2;
END LOOP;
Col_c2 := rtrim(Col_c2,1);
RETURN Col_c2;
SELECT REGEXP_SUBSTR('aa,bbb,cccc', '[^,]+', 1, rownum)
from dual?
connect by level = LENGTH(regexp_replace('aa,bbb,cccc', '[^,]+', ''));
with baseData as(
select '1' id,'aaa' name from dual
union all
select '2' ,'bbb' from dual
)
SELECT listagg(name?,',') WITHIN GROUP (ORDER BY id)
FROM? baseData?;