行转列之随着记录数增加,列数不固定,且不是多少条行边多少列

具体描述不出来,看图片:

行转列之随着记录数增加,列数不固定,且不是多少条行边多少列_第1张图片

附上建表语句:

create table TAB1
(
  id    VARCHAR2(6),
  iname VARCHAR2(20),
  sno   VARCHAR2(6)
)


 

insert into tab1(id,iname,sno) values('1001','abcde','s001');
insert into tab1(id,iname,sno) values('1002','hijk','s002');
insert into tab1(id,iname,sno) values('1002','hijk','s003');
insert into tab1(id,iname,sno) values('1003','xyz','s001');
insert into tab1(id,iname,sno) values('1003','xyz','s003');
insert into tab1(id,iname,sno) values('1003','xyz','s004');
insert into tab1(id,iname,sno) values('1004','abc','s005');
insert into tab1(id,iname,sno) values('1004','abc','s006');
insert into tab1(id,iname,sno) values('1005','def','s002');
insert into tab1(id,iname,sno) values('1005','def','s004');



 

需要实现的是

行转列之随着记录数增加,列数不固定,且不是多少条行边多少列_第2张图片

根据上一个blog写的方法,可以一步一步的想

第一步,明显需要的结果中是根据ID 或者INAME分组且按窗口排序,这时想到如下sql:

SELECT 'SELECT id,iname,' ||
       WMSYS.WM_CONCAT('MAX(DECODE(sn,''' || SN || ''',sno)) AS "供应商' || SN || '"') ||
       ' FROM (SELECT id, iname, sno, ROW_NUMBER() OVER(PARTITION BY id ORDER BY sno) sn FROM tab1)
 GROUP BY id,iname'
  FROM (SELECT ID,
               INAME,
               SNO,
               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY SNO) SN
          FROM TAB1);

会得到如下的结果:

SELECT ID,
       INAME,
       MAX(DECODE(SN, '1', SNO)) AS "供应商1",
       MAX(DECODE(SN, '1', SNO)) AS "供应商1",
       MAX(DECODE(SN, '2', SNO)) AS "供应商2",
       MAX(DECODE(SN, '1', SNO)) AS "供应商1",
       MAX(DECODE(SN, '2', SNO)) AS "供应商2",
       MAX(DECODE(SN, '3', SNO)) AS "供应商3"
  FROM (SELECT ID,
               INAME,
               SNO,
               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY SNO) SN
          FROM TAB1)
 GROUP BY ID, INAME

行转列之随着记录数增加,列数不固定,且不是多少条行边多少列_第3张图片

但是显然不是我们所需要的,因为列数重复了,且多了

于是,又想到第二步,可以在最外面的表中,只查到唯一的sn,所以有如下的SQL:

SELECT 'SELECT id,iname,' ||
       WMSYS.WM_CONCAT('MAX(DECODE(sn,''' || SN || ''',sno)) AS "供应商' || SN || '"') ||
       ' FROM (SELECT id, iname, sno, ROW_NUMBER() OVER(PARTITION BY id ORDER BY sno) sn FROM tab1)
 GROUP BY id,iname
 ORDER BY id;'
  FROM (SELECT DISTINCT ROW_NUMBER() OVER(PARTITION BY ID ORDER BY SNO) SN
          FROM TAB1);

得到sql如下:

SELECT ID,
       INAME,
       MAX(DECODE(SN, '1', SNO)) AS "供应商1",
       MAX(DECODE(SN, '2', SNO)) AS "供应商2",
       MAX(DECODE(SN, '3', SNO)) AS "供应商3"
  FROM (SELECT ID,
               INAME,
               SNO,
               ROW_NUMBER() OVER(PARTITION BY ID ORDER BY SNO) SN
          FROM TAB1)
 GROUP BY ID, INAME
 ORDER BY ID;

行转列之随着记录数增加,列数不固定,且不是多少条行边多少列_第4张图片

至此,达到我们的需求

这是我上篇blog的活学活用,虽然例子是我朋友的,但是也给他解决了很久之前的一个问题,吼吼

你可能感兴趣的:(oracle开发)