最近在使用Oracle时碰到这种情况:一个公司的同一关联人存在多种关联关系,数据类似下表:
![]()
为了便于分析,需要按不同公司将同一关联人的关联关系合并显示,如上表中赵一的“法人代表”和“股东”显示为一条记录,即实现“列转行”效果。
这时,使用listagg()函数即可。
一、数据准备:
1.创建数据表
- create table tmp_20190720
复制代码- cust_num VARCHAR2(20) not null,
复制代码- cust_name VARCHAR2(30) not null,
复制代码- relative_name VARCHAR2(30) not null,
复制代码- relationship VARCHAR2(30) not null
复制代码 2.插入示例数据
- insert into tmp_20190720 values ('A001','公司1','赵一','法人代表');
复制代码- insert into tmp_20190720 values ('A001','公司1','赵一','股东');
复制代码- insert into tmp_20190720 values ('A002','公司2','孙二','法人代表');
复制代码- insert into tmp_20190720 values ('A002','公司2','李四','股东');
复制代码- insert into tmp_20190720 values ('A003','公司3','张三','实际控制人');
复制代码- insert into tmp_20190720 values ('A003','公司3','张三','法人代表');
复制代码- insert into tmp_20190720 values ('A003','公司3','张三','资本构成');
复制代码 二、使用listagg()函数
方法一:使用listagg() + group by 直接聚类
- select a.cust_num, a.cust_name, a.relative_name,
复制代码- listagg(a.relationship,'|') within group (order by a.relationship) relation_all
复制代码- group by a.cust_num, a.cust_name, a.relative_name
复制代码 代码解析:
![]()
运行结果:
![]()
方法二:使用listagg() + over (partition by ) 窗口函数
- select distinct a.cust_num, a.cust_name, a.relative_name,
复制代码- listagg(a.relationship,'|') within group (order by a.relationship)
复制代码- over (partition by a.cust_num, a.cust_name, a.relative_name) relation_all
复制代码 代码解析:
![]()
运行结果:
两种方法的运行效果一致。
三、结束语
还有一个函数wm_concat()能实现类似的效果,参考代码如下:
- select a.cust_num, a.cust_name, a.relative_name,
复制代码- wmsys.wm_concat(a.relationship) relation_all
复制代码- group by a.cust_num, a.cust_name, a.relative_name
复制代码 但是,Oracle 12c版本已经不推荐使用此函数,并且不作为内置函数。wm_concat()还有局限性,其不支持拼接字段排序,不能自定义分隔符(默认为逗号)。如确实需要在12c版本使用此函数,可以采用重写wm_concat()函数的方式,具体代码可在网络中方便的找到。例如,可参考文章:
- https://www.cnblogs.com/wangyong/p/6254872.html
复制代码 以上,简要记录,防止遗忘。供参考。
|
|