1

我有一个正常的选择查询,结果如下输出。

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

4 回答 4

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 的最新添加,因此我倾向于使用此方法。

于 2013-09-16T11:12:17.903 回答
0

更通用的解决方案是使用UNPIVOT 和 PIVOT
temp_table已经是一个以(x1 x2 x3 x4)作为x-axisfy作为y-axis的数据透视表。
首先我们需要 UNPIVOTtemp_table进入unpivoted_temp_table然后 PIVOT 它以fy作为 x 轴和(x1 x2 x3 x4)作为 y 轴:

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

于 2013-09-16T13:13:29.737 回答
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))
于 2013-09-17T07:05:07.443 回答
0

在 Oracle 11G 中转置的三个可能选项

  • 解码选项

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

    • 湾。如果要转置而不是汇总,请对新列使用 MAX 和 DECODE

  • 使用枢轴

  • 使用 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。

于 2013-09-16T13:14:44.803 回答