Oracle中的多行转单行的函数

112 阅读1分钟

Oracle中提供了两个聚合函数用于将多行转为单行:

 1、wm_concat函数 

 2、listagg函数

假设有一个组织机构表org,其中id是主键,pid是父级id,level是机构所在层级,name是组织机构名称。

对于wm_concat函数和listagg函数,listagg支持自定义分隔符,wm_concat只能使用逗号作为分隔符,如果需要排序,更推荐使用listagg函数,如果不需要排序,更推荐使用wm_concat函数,如果需要指定分隔符,那就只能使用listagg函数了,如果将结果集作为一个子查询的话,也只能使用listagg函数,以下是一个用例:

需求:将一个组织机构的完整路径使用逗号分隔符查询出来。

使用listagg函数实现的SQL如下:

select listagg(name,',') within group(order by level)
from (
select * from org start with id='1120'connect by nocycle prior pid=id)

使用wm_concat函数实现的SQL如下:

select to_char(wm_concat(name)) 
from (
select * from org start with id='1120' connect by nocycle prior pid=id order by level)

由于wm_concat函数、listagg函数,支持根据分组、单条件进行多行转单行,但如果没办法分组,又想要将每个节点的全路径都查询出来,就需要使用sys_connect_by_path函数了。

以下是一个使用sys_connect_by_path函数的用例:

将所有组织机构的完整路径使用逗号分隔符查询出来,SQL如下:

select id, trim(',' from sys_connect_by_path(name,','))
from org start with pid is null connect by prior id=pid

使用trim将字符串中前后多出来分隔符删除。