【问题标题】:Using pivot on multiple columns of an Oracle row在 Oracle 行的多个列上使用数据透视
【发布时间】:2014-07-19 07:22:32
【问题描述】:

我在 Oracle 表 (tab1) 中有以下示例数据,我正在尝试将行转换为列。我知道如何在一列上使用 Oracle Pivot。但是可以将它应用于多个列吗?

样本数据:

Type  weight  height  
A     50      10  
A     60      12  
B     40      8  
C     30      15  

我的预期输出:

A-count B-count C-count A-weight B-weight C-weight A-height B-height C-height  
2       1       1       110      40       30       22       8        15  

我能做什么:

with T AS 
(select type, weight from tab1 )
select * from T
PIVOT (
count(type)
for type in (A, B, C, D,E,F)
)  

上面的查询给了我下面的结果

A B C  
2 1 1  

我可以用sum(weight)sum(height) 替换count(*) 来调整高度或重量。我想做但做不到的是,在一个查询中以所有三个(计数、体重和身高)为中心。

可以用pivot来完成吗?

【问题讨论】:

  • 非常好的问题,谢谢!

标签: sql oracle oracle11g pivot


【解决方案1】:

作为the documentation shows,您可以有多个聚合函数子句。所以你可以这样做:

select * from (
  select * from tab1
)
pivot (
  count(type) as ct, sum(weight) as wt, sum(height) as ht
  for type in ('A' as A, 'B' as B, 'C' as C)
);

A_CT A_WT A_HT B_CT B_WT B_HT C_CT C_WT C_HT
---- ---- ---- ---- ---- ---- ---- ---- ----
   2  110   22    1   40    8    1   30   15 

如果您希望列按您显示的顺序,则添加另一个级别的子查询:

select a_ct, b_ct, c_ct, a_wt, b_wt, c_wt, a_ht, b_ht, c_ht
from (
  select * from (
    select * from tab1
  )
  pivot (
    count(type) as ct, sum(weight) as wt, sum(height) as ht
    for type in ('A' as A, 'B' as B, 'C' as C)
  )
);

A_CT B_CT C_CT A_WT B_WT C_WT A_HT B_HT C_HT
---- ---- ---- ---- ---- ---- ---- ---- ----
   2    1    1  110   40   30   22    8   15 

SQL Fiddle.

【讨论】:

    【解决方案2】:

    第二种命名列的方法更好,可以解决更多问题。我有一个要求,我想总结从 PIVOT 返回的数据,所以有了列名,我可以简单地添加 2 并在第三个中获得所需的结果 -

    select a_ct, b_ct, c_ct, a_wt, b_wt, c_wt, a_ht, b_ht, c_ht, a_wt + b_wt + c_wt tot_wt
    from (
      select * from (
        select * from tab1
      )
      pivot (
        count(type) as ct, sum(weight) as wt, sum(height) as ht
        for type in ('A' as A, 'B' as B, 'C' as C)
      )
    );
    
    A_CT B_CT C_CT A_WT B_WT C_WT A_HT B_HT C_HT TOT_WT
    ---- ---- ---- ---- ---- ---- ---- ---- ---- ------
       2    1    1  110   40   30   22    8   15 180
    

    请注意,如果使用的 PIVOT 列之一返回 null,聚合函数(如 sum)将不会按预期运行,在这种情况下,我使用 CASE 语句来解决它。

    希望对某人有所帮助。

    【讨论】:

      【解决方案3】:

      Alex Poole 的回答非常棒,对我的 Oracle 查询很有帮助。这让我很好奇,在这里我将快速指出 Oracle for Microsoft PIVOT 多列的语法比较。这是我实际上将授予 Oracle SQL Simpler Syntax Award 的一个领域(这是我创建的一个虚构的奖项)。

      当需要旋转多个列时,Microsoft SQL 几乎没有那么简单和灵活。

      • 您必须连接原始分组字段以使其与众不同
      • 列名别名在 MSFT SQL 中更加手动;下面的代码没有别名
      • 您必须进行多次 PIVOT 调用
      • 您必须为 PIVOT 函数设置别名以避免语法错误
      • 即使考虑了所有这些因素,它仍然无法按预期分组
      • 最重要的是,Oracle 赢得了 SQL 更简单语法奖

      给定相同的数据集:

      DECLARE @tblSampleData AS table (Type nvarchar(10), Weight numeric(5,2), Height numeric(5,2))
      
      INSERT INTO @tblSampleData (Type, Weight, Height)
      VALUES
      ('A',     50,      10) 
      ,('A',     60,      12) 
      ,('B',     40,      8 )
      ,('C',     30,      15)
      

      微软 SQL:

      select * from 
      (
          select 
              *
              ,concat(Type,'1') as "Type1" 
              ,concat(Type,'2') as "Type2"
          from @tblSampleData
      ) AS src
      pivot (
          count(Type) --as ct, sum(weight) as wt, sum(height) as ht
          for Type in ([A], [B], [C])
      ) AS pvt1
      pivot (
          sum(weight) --as ct, sum(weight) as wt, sum(height) as ht
          for Type1 in ([A1], [B1], [C1])
      ) AS pvt1
      pivot (
          sum(height) --as ct, sum(weight) as wt, sum(height) as ht
          for Type2 in ([A2], [B2], [C2])
      ) AS pvt1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-19
        • 2021-11-25
        • 2013-02-22
        • 1970-01-01
        • 1970-01-01
        • 2013-05-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多