如何在Oracle中将行转换为列?

时间:2012-05-08 12:03:31

标签: sql oracle oracle10g pivot

我在Oracle数据库中有如下所示的数据表。

emp_num  person_name  organization  earned_date  sum(hours)
-------  -----------  ------------  -----------  ----------
36372    Name1        Test1         23-MAR-11      3.17
36372    Name1        Test1         15-MAR-11      6.70
40208    Name2        Test2         08-APR-11     13.50
40208    Name2        Test2         06-APR-11     12.07

我需要更改下面的查询输出。我怎么能这样做?

emp_num  person_name  organization  23-MAR-11  15-MAR-11  08-APR-11  06-APR-11
-------  -----------  ------------  ---------  ---------  ---------  ---------
36372     Name1       Test1           3.17        6.70      
40208     Name2       Test2                                 13.50      12.70     

2 个答案:

答案 0 :(得分:1)

除非使用某种形式的动态SQL,否则无法动态命名表中的列。但是,您可以使用通用日期列获得所需内容:

select emp_num, person_name, organization, 
       sum(decode(datenum, 1, hours, 0)) as date1hours,
       sum(decode(datenum, 2, hours, 0)) as date2hours,
       ...
       min(decode(datenum, 1, earned_date) as date1,
       min(decode(datenum, 2, earned_date) as date2,
       ...
from 
(
  select t.*, 
     dense_rank() over (partition by NULL order by earned_date) as datenum
  from the_table t
) t
group by emp_num, person_name, organization 

顺便说一句,Oracle 10g支持CASE语法,我建议您使用它而不是decode

答案 1 :(得分:0)

select
  emp_num,
  person_name,
  organization,
  sum(decode(earned_date,to_date('23/03/2011','dd/mm/yyyy'),hours,0)) 23mar11,
  sum(decode(earned_date,to_date('15/03/2011','dd/mm/yyyy'),hours,0)) 15mar11,
  sum(decode(earned_date,to_date('08/04/2011','dd/mm/yyyy'),hours,0)) 08apr11,
  sum(decode(earned_date,to_date('06/04/2011','dd/mm/yyyy'),hours,0)) 06apr11
from
  the_table //don't know the name
group by
  emp_num,
  person_name,
  organization

始终使用to_date函数将日期与字符串进行比较,我在这里使用了一种常见的英国格式。