|
WM_CONCAT(colName)为Oracle 10g中行数据转列数据的内置函数,执行效果如下
表T
A B
------------
1 2
1 3
1 4
2 1
2 3
执行语句 :
SELECT A, WM_CONCAT(B) B FROM T GROUP BY A
执行结果:
A B
---------------
1 2,3,4
2 1,3
注意:
当在包体内使用行转列时,WM_CONCAT(colName)可以使用,但WM_CONCAT(DISTINCT colName)会在包编译时会报错,
例如,在某一包的某一存储过程中有如下语句:
1 UPDATE D_LOWAREA L
2 SET L.BYQXH = (SELECT /*+index(b)*/
3 WM_CONCAT(DISTINCT XH.XHMC)
4 FROM OLIVE.OL$_ASSOCIATIONS A,
5 PMSBI.F_SB_SBXX_BASIC B,
6 PMSBI.D_XH XH
7 WHERE A.A IN (L.PDBYQ1, L.PDBYQ2, L.PDBYQ3)
8 AND A.B = B.SBBH
9 AND B.XHDM != 'wz'
10 AND B.XHDM = XH.XHDM);
11 COMMIT;
编译时会报如下错误:
PL/SQL:ORA-30482:DISTINCT option not allowed for this function.
解决方案:
使用动态SQL(字符串中有单引号由两个单引号表示):
1 EXECUTE IMMEDIATE
2 'UPDATE D_LOWAREA L
3 SET L.BYQXH = (SELECT /*+index(b)*/
4 WMSYS.WM_CONCAT(DISTINCT XH.XHMC)
5 FROM OLIVE.OL$_ASSOCIATIONS A,
6 PMSBI.F_SB_SBXX_BASIC B,
7 PMSBI.D_XH XH
8 WHERE A.A IN (L.PDBYQ1, L.PDBYQ2, L.PDBYQ3)
9 AND A.B = B.SBBH
10 AND B.XHDM != ''wz''
11 AND B.XHDM = XH.XHDM)';
12 COMMIT;
PS:Oracle 11g以上版本可以用LISTAGG实现行转列,写法如下:
SELECT A, LISTAGG(B, ',') WITHIN GROUP(ORDER BY B) B FROM T GROUP BY A
|
|