转置查询输出

时间:2013-09-16 10:58:08

标签: sql oracle11g transpose

我有一个正常的选择查询,它会在输出后生成。

select cid,x1,x2,x3,x4,fy
  from temp_table;

cid     x1  x2  x3  x4  fy
----------------------------
6657    100 0   0   200 2014
6658    300 0   0   400 2015
6659    500 0   0   600 2016

我希望它在输出后重写它。

    2014    2015    2016    
-------------------------   
x1  100     300     500     
x2  0       0       0       
x3  0       0       0       
x4  200     400     600 

如何实现这一目标?

4 个答案:

答案 0 :(得分:1)

以下是仅使用子查询和聚合执行此操作的方法:

select name,
       sum(case when fy = 2014 then x end) as "2014",
       sum(case when fy = 2015 then x end) as "2015",
       sum(case when fy = 2016 then x end) as "2016"
from (select fy,
             (case when n.n = 1 then 'x1'
                   when n.n = 2 then 'x2'
                   when n.n = 3 then 'x3'
                   when n.n = 4 then 'x4'
              end) as name,
             (case when n.n = 1 then x1
                   when n.n = 2 then x2
                   when n.n = 3 then x3
                   when n.n = 4 then x4
              end) as x
      from temp_table cross join
            (select 1 as n from dual union all
             select 2 from dual union all
             select 3 from dual union all
             select 4 from dual
            ) n
     ) t
group by name;

您也可以使用pivot,但这是Oracle SQL的最新成员,因此我倾向于使用此方法。

答案 1 :(得分:0)

更一般的解决方案是使用UNPIVOT and PIVOT 您的temp_table已经是一个数据透视表,(x1 x2 x3 x4) x轴 fy y轴即可。
首先,我们需要将temp_table UNPIVOT转换为unpivoted_temp_table,然后将 fy 作为x轴并将(x1 x2 x3 x4)作为y- PIVOT轴:

with unpivoted_temp_table as (

SELECT *
  FROM   temp_table
  UNPIVOT (
          totalSales                            
          FOR x                             
          IN  (x1, x2, x3, x4)
         )
)  

select *  
FROM   unpivoted_temp_table 
  PIVOT (
               SUM(totalSales)        
           FOR fy          
          IN (2014, 2015, 2016)
         )
order by 1 --order by column X

http://sqlfiddle.com/#!4/4fdfc/1/0

答案 2 :(得分:0)

在Oracle 11G中进行转置的三种可能选项

  • DECODE选项

    • 一个。如果要转置,请对新列使用SUM和DECODE

    • 湾如果要转置,请使用MAX和DECODE作为新列 而不是总结

  • 使用PIVOT

  • 如Gordon所说,使用WITH和SUB SELECT

要使用数据透视表,您的代码中无法使用数据集,因为您的初始数据集已经过旋转。

WITH TEMP1
    AS (SELECT
             6657 AS CID,
             100 AS VAL,
             'X1' AS XCORD,
             2014 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6657 AS CID,
             0 AS VAL,
             'X2' AS XCORD,
             2014 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6657 AS CID,
             0 AS VAL,
             'X3' AS XCORD,
             2014 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6657 AS CID,
             200 AS VAL,
             'X4' AS XCORD,
             2014 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6658 AS CID,
             300 AS VAL,
             'X1' AS XCORD,
             2015 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6658 AS CID,
             0 AS VAL,
             'X2' AS XCORD,
             2015 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6658 AS CID,
             0 AS VAL,
             'X3' AS XCORD,
             2015 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6658 AS CID,
             400 AS VAL,
             'X4' AS XCORD,
             2015 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6659 AS CID,
             500 AS VAL,
             'X1' AS XCORD,
             2016 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6659 AS CID,
             0 AS VAL,
             'X2' AS XCORD,
             2016 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6659 AS CID,
             0 AS VAL,
             'X3' AS XCORD,
             2016 AS FY
        FROM
             DUAL
        UNION ALL
        SELECT
             6659 AS CID,
             600 AS VAL,
             'X4' AS XCORD,
             2016 AS FY
        FROM
             DUAL)
SELECT
      *
FROM
      (SELECT
            XCORD,
            FY,
            SUM ( VAL ) AS VAL
       FROM
            TEMP1
       GROUP BY
            XCORD,
            FY) PIVOT (SUM ( VAL ) FOR FY IN ('2014', '2015', '2016'))
ORDER BY
      XCORD;

结果:

XCORD   '2014'  '2015'  '2016'
-----   ------  ------  ------
X1  100 300 500
X2  0   0   0
X3  0   0   0
X4  200 400 600

如果查看数据集,可以看到结果

CID     VAL     XCORD   FY
----    ----    -----   ----
6657    100 X1  2014
6657    0   X2  2014
6657    0   X3  2014
6657    200 X4  2014
6658    300 X1  2015
6658    0   X2  2015
6658    0   X3  2015
6658    400 X4  2015
6659    500 X1  2016
6659    0   X2  2016
6659    0   X3  2016
6659    600 X4  2016

或多或少是您的数据的UNPIVOT。

答案 3 :(得分:0)

你可以通过unpivot和pivot的组合来实现。

select * from 
    (select * from 
    (select x1,x2,x3,x4,fy from table1) 
    unpivot(val for x in (x1,x2,x3,x4)))
pivot(sum(val) for fy in (2014,2015,2016))