将一列多行转为一个字符串连接显示,oracle该如何实现,如下的例子:
create table stu(stuid int, stuname varchar2(32));
create table cls(stuid int, clsname varchar2(32));
insert into stu values(1, '张三');
insert into stu values(2, '李四');
insert into stu values(3, '王五');insert into cls values(1, '语文');
insert into cls values(1, '数学');
insert into cls values(3, '语文');
insert into cls values(3, '英语');
insert into cls values(3, '物理');我查询学生选了哪些课程,结果为---------------------------------------------------------
stuid             stuname              clsname
1                   张三        语文,数学
2                   李四         
3                   王五        语文,英语,物理我使用sys_connect_by_path函数来实现,有问题,请高手指导一下,谢谢了!!!
select stuid, stuname, (select max(substr(sys_connect_by_path(clsname,','),2)) 
       from (select clsname,rownum rn from cls where stuid=stu.stuid) start with rn=1 connect by rn=rownum) clsname 
from stu;

解决方案 »

  1.   


    select stu.stuid,
           stu.stuname,
           wm_concat(cls.clsname)
    from stu,cls
    where stu.stuid=cls.stuid
    group by stu.stuid,stu.stuname--或者(未测试)
    select stuid,
           stuname,
           replace(substr(max(sys_connect_by_path(clsname,';')),2),';','') newname
    from (select stuid,
                 stuname,
                 clsname,
                 rn,
                 lead(rn) over(partition by stuid,stuname order by rn) rn1
          from (select stu.stuid,
                       stu.stuname,
                       cls.name,
                       rownum rn
                 from cls,stu
               where cls.stuid=stu.stuid)
          )
    start with rn1 is null
    connect by rn1=prior rn
    group by stuid,stuname
      

  2.   


    create table stu(stuid int, stuname varchar2(32));
    create table cls(stuid int, clsname varchar2(32));
    insert into stu values(1, '张三');
    insert into stu values(2, '李四');
    insert into stu values(3, '王五');insert into cls values(1, '语文');
    insert into cls values(1, '数学');
    insert into cls values(3, '语文');
    insert into cls values(3, '英语');
    insert into cls values(3, '物理');select s.stuid, s.stuname, wm_concat(c.clsname)
      from stu s, cls c
     where s.stuid = c.stuid
     group by s.stuid, s.stuname
    1 张三 语文,数学
    3 王五 语文,物理,英语
      

  3.   


    create table stu(stuid int, stuname varchar2(32));
    create table cls(stuid int, clsname varchar2(32));
    insert into stu values(1, '张三');
    insert into stu values(2, '李四');
    insert into stu values(3, '王五');insert into cls values(1, '语文');
    insert into cls values(1, '数学');
    insert into cls values(3, '语文');
    insert into cls values(3, '英语');
    insert into cls values(3, '物理');select s.stuid, s.stuname,wm_concat(c.clsname)
      from stu s, cls c
     where s.stuid= c.stuid(+)
     group by s.stuid, s.stunames.stuid  s.stuname wm_concat(c.clsname)
    1  张三    语文,数学
    2  李四
    3  王五    语文,物理,英语
      

  4.   

    谢谢各位的帮助,我的oracle是9i的不支持wm_concat函数,另外由于我实际用的查询语句比较复杂,这里只是举个例子,怎么样能在子查询中实现
      

  5.   

    像这样作为子字段出现,该如何实现,条件改为stuid=1单个实现可以,为什么stu.stuid联立条件就不行 ?
    (select max(substr(sys_connect_by_path(clsname,','),2))  
      from (select clsname,rownum rn from cls where stuid=stu.stuid) start with rn=1 connect by rn=rownum) clsname  
      

  6.   


    LZ, 你上面的报错的因为在标量子查询里面有嵌套了子查询,
    所以识别不了 stu这个表名了
    改成下面这个就可以了SELECT stuid
          ,stuname
          ,(SELECT MAX(substr(sys_connect_by_path(clsname, ','), 2))
              FROM (SELECT clsname
                          ,stuid
                          ,row_number() over(PARTITION BY stuid ORDER BY clsname) rn
                      FROM cls) t
             START WITH rn = 1
                    AND t.stuid = v.stuid
            CONNECT BY rn = PRIOR rn + 1
                   AND stuid = PRIOR stuid
             GROUP BY stuid  --必须要加这个GROUP BY,负责会报错,估计是9i的BUG
              ) clsname
      FROM stu v;或者可以使用 自定义函数 ,更简单一些
    SELECT stuid
          ,stuname
          ,(SELECT stragg(clsname || ',') FROM cls t WHERE t.stuid = v.stuid) clsname
      FROM stu v;