我在 Oracle 表 (
tab1
) 中有以下示例数据,我正在尝试将行转换为列。我知道如何在某一列上使用 Oracle 数据透视表。但是否可以将其应用于多个列?
样本数据:
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
我可以用
count(*)
或 sum(weight)
替换 sum(height)
来调整身高或体重。我想要做但我做不到的事情是在一个查询中对所有三个(计数、重量和高度)进行旋转。
可以使用pivot来完成吗?
如文档所示,您可以有多个聚合函数子句。所以你可以这样做:
select *
from (
select type, weight, height 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 *
(通常应该避免使用,除了临时查询或内部查询):
select a_ct, b_ct, c_ct, a_wt, b_wt, c_wt, a_ht, b_ht, c_ht
from (
select type, weight, height 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 |
如果这些是表中唯一的列,那么您不需要任何子查询:
select a_ct, b_ct, c_ct, a_wt, b_wt, c_wt, a_ht, b_ht, c_ht
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)
);
...但是如果还有其他列,您将获得比预期更多的行。
第二种命名列的方法更好,可以解决更多问题。我有一个要求,我想汇总从 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 语句来解决它。
希望它对某人有帮助。
Alex Poole 的回答非常棒,对我的 Oracle 查询很有帮助。 这让我很好奇,在这里我将快速指出 Oracle for Microsoft PIVOT 多列的语法比较。 在这一领域,我实际上会授予 Oracle SQL 更简单语法奖(这是我创建的一个虚构奖项)。
当需要旋转多个列时,Microsoft 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