在Oracle SQL中将列转换为行

时间:2017-09-26 09:07:13

标签: sql oracle

请考虑此表:

表1

NUMBER        NAME       
----------------------
01              A              
01              B        
02              A        
01              C        
02              C
03              C
04              C

我想将其转换为

表2

NAME    NUM01   NUM02   NUM03   NUM04   NUM05
--------------------------------------------------
A       01      02      NULL    NULL    NULL
B       01      NULL    NULL    NULL    NULL
C       01      02      03      04      NULL

表2 中,列数固定为(NUM01->05)。如果NAME值的值超过 5 NUMBER ,则只选择前5个。如果值小于5,则在剩余列中填写 NULL

我在NAME列中有许多不同的值,因此我无法想出正确转换 Table1 的方法。

请帮帮我。

1 个答案:

答案 0 :(得分:1)

您的“数字”值似乎是字符串,除非您使用带引号的标识符,否则您不能拥有名为number的列,因此我已替换value来创建示例数据:

create table table1(value varchar2(7), name varchar2(4));
insert into table1 (value, name)
select '01', 'A' from dual
union all select '01', 'B' from dual
union all select '02', 'A' from dual
union all select '01', 'C' from dual
union all select '02', 'C' from dual
union all select '03', 'C' from dual
union all select '04', 'C' from dual
/

您可以使用分析函数为每个值指定行号或排名:

select name, value,
  row_number() over (partition by name order by value) as rn
from table1;

NAME VALUE           RN
---- ------- ----------
A    01               1
A    02               2
B    01               1
C    01               1
C    02               2
C    03               3
C    04               4

然后你可以pivot that query(只要你在11g或更高)获得你想要的结果:

select *
from (
  select name, value,
    row_number() over (partition by name order by value) as rn
  from table1
)
pivot (max(value) as value for (rn) in (1, 2, 3, 4, 5));

NAME 1_VALUE 2_VALUE 3_VALUE 4_VALUE 5_VALUE
---- ------- ------- ------- ------- -------
A    01      02                             
B    01                                     
C    01      02      03      04             

透视操作会忽略排名高于5的任何内容。