2012-10-25 34 views
3

我有一个表,看起来像这样:动态旋转表甲骨文

C_ID P_ID KEY VALUE 
null null KEY1 VALUE1 
null null KEY2 VALUE2 
null null KEY3 VALUE3 
2  2  KEY4 VALUE4 
2  3  KEY5 VALUE5 

我想这个结果表/视图:

C_ID P_ID KEY1 KEY2 KEY3  KEY4 KEY5 
NULL NULL VALUE1 VALUE2 VALUE3  NULL NULL 
2  2  NULL NULL NULL  VALUE4 NULL 
2  3  NULL NULL NULL  NULL VALUE5 

大家有一个想法,我怎么能做到这一点? 我有尝试过:

select * from (select c_id, p_id, r_key, r_value from s_projectroles) pivot (max(r_value) for r_key in (any)); 

我得到了一个错误:

ORA-00936: Ausdruck fehlt 
00936. 00000 - "missing expression" 

回答

9

这可以动态地做了以下的方法。首先,这里是查询的静态版本,所以你可以看到最终的SQL:

select c_id, 
    p_id, 
    max(case when r_key= 'KEY1' then r_value end) KEY1, 
    max(case when r_key= 'KEY2' then r_value end) KEY2, 
    max(case when r_key= 'KEY3' then r_value end) KEY3, 
    max(case when r_key= 'KEY4' then r_value end) KEY4, 
    max(case when r_key= 'KEY5' then r_value end) KEY5 
from s_projectroles 
group by c_id, p_id 

SQL Fiddle with Demo

然后动态地做到这一点,您可以创建以下过程:

CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor) 
as 
    sql_query varchar2(1000) := 'select c_id, P_id '; 

    begin 
     for x in (select distinct r_key from s_projectroles order by 1) 
     loop 
      sql_query := sql_query || 
       ' , max(case when r_key = '''||x.r_key||''' then r_value end) as '||x.r_key; 

       dbms_output.put_line(sql_query); 
     end loop; 

     sql_query := sql_query || ' from s_projectroles group by c_id, p_id'; 

     open p_cursor for sql_query; 
    end; 
/

然后执行它:

variable x refcursor 
exec dynamic_pivot(:x) 
print x 

的结果是相同的:

| C_ID | P_ID | KEY1 | KEY2 | KEY3 | KEY4 | KEY5 | 
---------------------------------------------------------------- 
| (null) | (null) | VALUE1 | VALUE2 | VALUE3 | (null) | (null) | 
|  2 |  2 | (null) | (null) | (null) | VALUE4 | (null) | 
|  2 |  3 | (null) | (null) | (null) | (null) | VALUE5 | 
+0

嗨bluefeet,它有点晚,但无论如何。我以类似的方式解决了。你的回答是正确的。谢谢 –