JasonFu

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

今天又有朋友讨论以下行列转换问题:
      编码  行  值
      AA   1  345
      BB   1  456
      CC   1  657
      DD   2  546
      EE   2  434
      FF   2  897
      GG   3  566 要实现如下转换
        1      2       3
      AA345   DD546   GG566
      BB456   EE434
      CC657   FD897
  
   关键点是行1,2,3有若干个,不是固定是3个。。

      create table test (a1 varchar2(10), a2 number(3), a3 varchar2(6));
      insert into test values('AA',1,'345');
      insert into test values('BB',1,'456');
      insert into test values('CC',1,'657');
      insert into test values('DD',2,'546');
      insert into test values('EE',2,'434');
      insert into test values('FF',2,'897');
      insert into test values('GG',3,'566');
      insert into test values('EE',1,'457');
      commit;
     
      SQL> select * from test;
     
      A1                 A2 A3
      ---------- ---------- ------
      AA                  1 345
      BB                  1 456
      CC                  1 657
      DD                  2 546
      EE                  2 434
      FF                  2 897
      GG                  3 566
      EE                  1 457
     
      with atest as
       (
       select icol*10+irow icol,irow, decode(icol,1,ivalue) c1 ,decode(icol,2,ivalue) c2, decode(icol,3,ivalue) c3
         from (
           select a2 icol, a1||a3 ivalue, row_number() over(partition by a2 order by a1||a3) irow from test)
       )
     
      select irow , ltrim(rtrim(max(sys_connect_by_path(c1,' ')))) c1,
      ltrim(rtrim(max(sys_connect_by_path(c2,' ')))) c2,
      ltrim(rtrim(max(sys_connect_by_path(c3,' ')))) c3 from atest
      connect by icol-10 = prior icol
      group by irow
     
     
      SQL> col c1 for a10;
      SQL> col c2 for a10;
      SQL> col c3 for a10;
      SQL> select irow , ltrim(rtrim(max(sys_connect_by_path(c1,' ')))) c1,
        2  ltrim(rtrim(max(sys_connect_by_path(c2,' ')))) c2,
        3  ltrim(rtrim(max(sys_connect_by_path(c3,' ')))) c3 from
        4  (
        5   select icol*10+irow icol,irow, decode(icol,1,ivalue) c1 ,decode(icol,2,ivalue) c2, decode(icol,3,ivalue) c3
        6     from (
        7       select a2 icol, a1||a3 ivalue, row_number() over(partition by a2 order by a1||a3) irow from test)
        8   )
        9  connect by icol-10 = prior icol
       10  group by irow
       11  ;
     
            IROW C1         C2         C3
      ---------- ---------- ---------- ----------
               1 AA345      DD546      GG566
               2 BB456      EE434
               3 CC657      FF897
               4 EE457
      

   Oracle10g 中, 还有函数 WMSYS.WM_CONCAT 可以使用, 如

   SQL>                WITH A AS (
           2           SELECT 1123 ID,'2008-9-19' DAY,'9:7:47' TIME FROM DUAL UNION
           3           SELECT 1123 ID,'2008-9-19' DAY,'19:7:47' TIME FROM DUAL  UNION
           4           SELECT 1123 ID,'2008-9-29' DAY,'13:7:47' TIME FROM DUAL  UNION
           5           SELECT 1123 ID,'2008-9-29' DAY,'12:7:47' TIME FROM DUAL )
           6           select ID,DAY,WMSYS.WM_CONCAT(TIME) TIME FROM A GROUP BY ID,DAY;
        
                 ID DAY       TIME
         ---------- --------- --------------------
               1123 2008-9-19 19:7:47,9:7:47
               1123 2008-9-29 12:7:47,13:7:47

posted on 2008-05-26 15:42  Jason.Fu  阅读(664)  评论(0编辑  收藏  举报