转换数据库表的行和列

时间:2012-11-08 10:23:26

标签: sql oracle pivot

我有数据库表。我进一步看到数据是以特定格式。如何在不使用查询直接创建临时表的情况下执行以下转换?col2不是静态字段X和Y,它是动态确定的,即列中的任何一个都不是动态的。 enter image description here

2 个答案:

答案 0 :(得分:2)

您没有指定您使用的是哪个版本的Oracle,因此这里有一些解决方案。

如果您使用的是Oracle 11g +,则可以访问PIVOT功能:

select *
from
(
  select col1, col2, col3
  from yourtable
) src
pivot
(
  max(col3)
  for col2 in ('X', 'Y')
) piv

请参阅SQL Fiddle with Demo

如果您使用的是其他版本的Oracle,则可以使用带有CASE语句的聚合函数:

select col1,
  min(case when col2 = 'X' then col3 end) X,
  min(case when col2 = 'Y' then col3 end) Y
from yourtable
group by col1

请参阅SQL Fiddle with Demo

如果你有一个未知数量的col2值,那么你可以在oracle中创建一个程序来生成动态sql:

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

    begin
        for x in (select distinct col2 from yourtable order by 1)
        loop
            sql_query := sql_query ||
                ' , min(case when col2 = '''||x.col2||''' then col3 end) as '||x.col2;

                dbms_output.put_line(sql_query);
        end loop;

        sql_query := sql_query || ' from yourtable group by col1';

        open p_cursor for sql_query;
    end;
/

然后执行它:

variable x refcursor
exec dynamic_pivot(:x)
print x

结果应该是一样的:

| COL1 |  X  |  Y |
--------------------
|    A |   1 |   3 |
|    B |   2 |   4 |

答案 1 :(得分:1)

select 
  col1 " ",
  sum(case when col2='X' then col3 else 0 end) x,
sum(case when col2='Y' then col3 else 0 end) y
from sample
group by col1

==

SQL Fiddle Demo for this problem

SQL Fiddle Screenshot