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将字符串中前后多出来分隔符删除。