使用Oracle SQL不使用聚合函数的数据透视表

时间:2018-12-19 13:59:39

标签: sql oracle oracle11g pivot unpivot

我的table1具有以下结构

          type month1 month2 month3 month4
           A     20    30      40    5
           B     10    30      50    7
           C     13    30      80    8

我正在尝试使用table1获得以下输出

          month    A   B   C
          month1  20   10  13
          month2  30   30  30
          month3  40   50  80
          month4  5    7   8

通常,它的sql将每一列都作为行。这里不需要聚合。

我写了以下sql

             select decode (TYPE,'A',month1,null) A,
             decode (TYPE,'B',month1,null) B,
             decode (TYPE,'C',month1,null) C
             from table1

但是给空值的明显原因是我在解码语句中添加了空值。 我确实尝试在解码中提供月份值,但由于一次解码将创建一行而无法正常工作。 有人可以在这里建议我更好的方法吗?

2 个答案:

答案 0 :(得分:1)

虽然解码会更好,但是您也可以使用UNION来获得相同的结果。

Select 'month1' as month
, sum(case when type = 'A' then month1 else null end) as A
, sum(case when type = 'B' then month1 else null end) as B
, sum(case when type = 'C' then month1 else null end) as C
from table1
group by 'month1'

UNION ALL

Select 'month2' as month
, sum(case when type = 'A' then month2 else null end) as A
, sum(case when type = 'B' then month2 else null end) as B
, sum(case when type = 'C' then month2 else null end) as C
from table1
group by 'month2'

UNION ALL

Select 'month3' as month
, sum(case when type = 'A' then month3 else null end) as A
, sum(case when type = 'B' then month3 else null end) as B
, sum(case when type = 'C' then month3 else null end) as C
from table1
group by 'month3'

UNION ALL

Select 'month4' as month
, sum(case when type = 'A' then month4 else null end) as A
, sum(case when type = 'B' then month4 else null end) as B
, sum(case when type = 'C' then month4 else null end) as C
from table1
group by 'month4'

SQL Fiddle

答案 1 :(得分:0)

您可以先在子查询中应用unpivot,然后将decodemonth进行分组:

select month, max(decode(type,'A',value)) as "A",
              max(decode(type,'B',value)) as "B",
              max(decode(type,'C',value)) as "C"
  from
  (
    with t ( type, month1, month2, month3, month4 ) as
    (
     select 'A',20,30,40,5 from dual union all
     select 'B',10,30,50,7 from dual union all
     select 'C',13,30,80,8 from dual
    )    
    select type, month, value 
      from
         ( Select *
             From t ) p
    unpivot  
       (value for month in
          ( month1, month2, month3, month4)  
    ) unpvt
   ) 
group by month
order by month;

MONTH   A   B   C
------  --  --  --
MONTH1  20  10  13
MONTH2  30  30  30
MONTH3  40  50  80
MONTH4  5   7   8

Rextester Demo