今天工作中遇到一个小需求就是 两张表 A表和B表 是1对N的关系。
要查询A表时 同样吧B表中对应的多条数据也查出来,并要求吧B表中的多条合成A表中的一个字段来显示。
create table A (A1 VARCHAR2,A2 VARCHAR2); --A2 对应 B1
create table B (B1 VARCHAR2,B2 VARCHAR2);
insert into A VALUES ('1','A');
insert into A VALUES ('2','AA');
insert into A VALUES ('3','AAA');
insert into B VALUES ('A','@@@');
insert into B VALUES ('A','####');
insert into B VALUES ('A','$$$');
insert into B VALUES ('AA','%%%');
insert into B VALUES ('AA','&&&');
select A1, (SELECT wm_concat(B2) FROM B where A.A2=B.B1 GROUP BY B1 ) FROM A;
或者 注意加了 distinct 关键字
select A1, (SELECT distinct wm_concat(B2) over (partition by b1) FROM B where A.A2=B.B1 ) FROM A;
可以看出 wm_concat()方法默认的链接符号是 , (逗号) 并且不能改变。官方也没查看相关该方法的文档说明。
然而 LISTAGG()方法就不一样了
首先看下官方的说明:
http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions089.htm#SQLRF30030
它可以指定链接符号,也可以省略。并且有排序功能
看执行结果1
select A1, (SELECT LISTAGG(B2,'<1>') WITHIN GROUP (ORDER BY b2 ) FROM B where A.A2=B.B1 ) FROM A;
看执行结果2 加上desc 后执行
select A1, (SELECT LISTAGG(B2,'<1>') WITHIN GROUP (ORDER BY b2 desc) FROM B where A.A2=B.B1 ) FROM A;
wm_concat()方法在不同的oracle版本中返回值的类型是不一样的 11g r1 为 字符型 11g r2 就成了 clob类型了。
推荐使用LISTAGG() 方法去列转行。 或者自定义个方法去实现行转列吧。
自定义方法参照此博客吧:
http://www.enkj.com/help/newscontent/110547