Oracle在执行时间之前旋转未知数量的列

时间:2015-03-13 12:16:41

标签: oracle oracle11g pivot

我有这样的事情:

id  cod
1   a
1   b
1   c
2   d
2   e
3   f
3   g

我需要这样的东西:

id  cod 1   cod 2   cod 3
1   a       b       c
2   d       e   
3   f       g   

你知道没有办法知道oracle在执行时间之前必须生成多少列。

3 个答案:

答案 0 :(得分:1)

您可以使用以下代码p_pivot。它根据您的表动态构建视图v_test。 然后你可以在这个视图中选择:

Connected to Oracle Database 10g Release 10.2.0.4.0 

SQL> execute p_pivot;

PL/SQL procedure successfully completed

SQL> select * from v_test;

        ID COD1  COD2  COD3
---------- ----- ----- -----
         1 a     b     c
         2 d     e     
         3 f     g     

程序(请将代码名称从test更改为代码中的表名称):

create or replace procedure p_pivot is
  v_cols number;
  v_sql varchar2(4000);
begin
  select max(cnt) into v_cols
    from (select count(1) cnt from test group by id);

  v_sql := 
  'create or replace view v_test as 
  with t as (select row_number() over (partition by id order by cod) rn, test.* from test)
  select id';

  for i in 1..v_cols
  loop
    v_sql := v_sql || ', max(decode(rn, '||i||', cod)) cod'||i;
  end loop;
  v_sql := v_sql || ' from t group by id';
  execute immediate v_sql;
end p_pivot;

答案 1 :(得分:0)

没有办法如何做到这一点。 Oracle需要知道编译查询时的列数。

想象一下,您使用此类查询创建视图。每次查看时,视图都会有不同的列数。

此外,如何从这样的查询中获取数据也无法实现。因为在评估表中的所有数据之前,您不知道有多少列。

答案 2 :(得分:0)

您好您也可以使用此查询。

- 创建测试数据

create table test_me(id_num  number,val varchar2(10));

insert all 

into test_me 

values(1,'a')

into test_me values (1,'b')

into test_me values (1,'c')

into test_me values (2,'d')

into test_me values (2,'e')

into test_me values (3,'f')

into test_me values (3,'g')

select 1 from dual;

select * from 

(

select id_num,val,row_number() over (partition by  id_num order by val) rn

from test_me )

pivot (max(val) for id_num in(1 as val_1,2 as val_2,3 as val_3));

SQLFiddle演示就在这里 http://sqlfiddle.com/#!4/4206f/ 1