oracle 分组拼接

  方法一:listagg, 参考链接,从oracle11g后出现的新函数

  如果拼接的字符串长度超过4000字节,会报ora-01489错误,ora-01489 字符串连接的结果过长 解决方案

SELECT 
	id,count(name) as countname,
	LISTAGG(to_char(name), ',') WITHIN GROUP(ORDER BY name) AS pjname
FROM 
(
	select 
		distinct B.id as id, 
		B.name as name
	from 
		B left join C on B.name = C.name
	where 
		C.gender = 'female'
)
group by id

  方法二:wmsys.wm_concat参考链接,返回结果类型会受版本影响,不建议使用

select 
	grp, wmsys.wm_concat(str)
from 
(
	select 1 grp, 'a1' str from dual
    union
    select 1 grp, 'a2' str from dual
    union
    select 2 grp, 'b1' str from dual
    union
    select 2 grp, 'b2' str from dual
    union
    select 2 grp, 'b3' str from dual
) t
group by
	grp

  方法三(1):sys_connect_by_path参考链接

select role_category,  
       ltrim(sys_connect_by_path(role_id, ','), ',') as role_id_list  
from   (  
        select role_category,  
               role_id,  
               (row_number() over(partition by role_category order by role_id))  
                  as row_number  
        from   (  
                select 'role_01' as role_id ,'admin' as role_category from dual  
                union all  
                select 'role_02' as role_id ,'admin' as role_category from dual  
                union all  
                select 'role_03' as role_id ,'normal' as role_category from dual  
                union all  
                select 'role_04' as role_id ,'normal' as role_category from dual  
                union all  
                select 'role_05' as role_id ,'normal' as role_category from dual  
                union all  
                select 'role_06' as role_id ,'normal' as role_category from dual  
                union all  
                select 'role_07' as role_id ,'normal' as role_category from dual  
                union all  
                select 'role_08' as role_id ,'normal' as role_category from dual  
               )  
       )  
where  connect_by_isleaf = 1  
       start with row_number = 1  
       connect by row_number - 1 = prior row_number  
       and role_category = prior role_category

  方法三(2):sys_connect_by_path参考链接

select 
	deptno,
	ltrim(max(sys_connect_by_path(ename, ',')), ',') name
from
(
	select 
		deptno, 
		ename, 
		row_number() over(partition by deptno order by ename) ro
    from 
	(
		select 
			deptno,ename
		from 
			emp 
		where 
			deptno is not null
	) t
) newtab
start with newtab.ro = 1
connect by prior newtab.ro = newtab.ro - 1
group by deptno;

  方法三(3):sys_connect_by_path参考链接

select 
	deptno,
	ltrim(max(sys_connect_by_path(ename, ',')), ',') name
from
(
	select 
		deptno, 
		ename, 
		ro,
		lead(ro) over(partition by deptno order by ro) ro_next
    from 
	(
		select 
			deptno, ename,
			row_number() over(order by deptno, ename) ro
		from 
			emp 
		where 
			deptno is not null
	) t
) newtab
start with ro_next is null
connect by ro_next = prior ro
group by deptno;

  

posted on 2019-06-03 16:37  iUpoint  阅读(4962)  评论(0编辑  收藏  举报

导航