我有一个数据集,它由几个关键字段、一个状态和一个计数组成。PIVOT做得很好,为我提供了每个关键字段一行的组合,每个状态一列。下面的示例:
with dataquery (field1, field2, field3, my_status, statcount) as (
select 'AAA', 'BBB', 'CCC', 'XX', 11 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 22 from dual
union
select 'AAA', 'BBB', 'CCC', 'ZZ', 33 from dual
),
pivotquery as (
SELECT field1,
field2,
field3,
xx_stat_count AS xx,
yy_stat_count AS yy,
zz_stat_count AS zz
FROM dataquery
PIVOT (
SUM (statcount) AS stat_count
FOR (my_status)
IN ('XX' AS XX,
'YY' AS yy,
'ZZ' AS zz
)
)
)
select * from pivotquery;
这给出了预期的结果:
FIELD1 FIELD2 FIELD3 XX YY ZZ
AAA BBB CCC 11 22 33
然而,如果我在数据中有额外的列,它不会像我预期的那样忽略它们并将其汇总。它似乎试图将未使用的列用作分组逻辑的一部分,而不是忽略它们。如果我将输入更改为:
with dataquery (field1, field2, field3, my_status, statcount, cnt2, cnt3, cnt4) as (
select 'AAA', 'BBB', 'CCC', 'XX', 11, 12, 13, 14 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 22, 22, 23, 24 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'ZZ', 33, 32, 33, 34 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 122, 32, 33, 34 as cnt4 from dual
)
我得到这个:
FIELD1 FIELD2 FIELD3 XX YY ZZ
AAA BBB CCC 22
AAA BBB CCC 122 33
AAA BBB CCC 11
而不是预期的
FIELD1 FIELD2 FIELD3 XX YY ZZ
AAA BBB CCC 11 144 33
如果我进一步更改输入数据,这样就不会重复其他字段,它显示为4行:
with dataquery (field1, field2, field3, my_status, statcount, cnt2, cnt3, cnt4) as (
select 'AAA', 'BBB', 'CCC', 'XX', 11, 12, 13, 14 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 22, 22, 23, 24 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'ZZ', 33, 32, 33, 34 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 122, 132, 33, 34 as cnt4 from dual
)
给出
FIELD1 FIELD2 FIELD3 XX YY ZZ
AAA BBB CCC 22
AAA BBB CCC 33
AAA BBB CCC 122
AAA BBB CCC 11
这是预期的行为吗?
我可以绕过它,要么事先添加一个子查询,只选择PIVOT处理的字段1、字段2、字段3、mystatus和statcount,要么在之后进行选择/分组,将事情汇总起来。
这是预期行为吗?
是,来自SELECT
文档:
pivot_clause
计算在子句开头指定的聚合函数。聚合函数必须指定GROUP BY
子句才能返回多个值,但pivot_clause
不包含显式GROUP BY
子句。相反,pivot_clause
执行隐式GROUP BY
。隐式分组基于pivot_clause
中未引用的所有列,以及pivot_in_clause
中指定的值集。(。如果指定了多个聚合函数,则必须至少为除一个聚合函数之外的所有聚合函数提供别名。
若要解决此问题,请仅对SELECT
所需列使用子查询,以便其他列不会隐式用作GROUP BY
子句:
with dataquery (field1, field2, field3, my_status, statcount, cnt2, cnt3, cnt4) as (
select 'AAA', 'BBB', 'CCC', 'XX', 11, 12, 13, 14 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 22, 22, 23, 24 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'ZZ', 33, 32, 33, 34 as cnt4 from dual
union
select 'AAA', 'BBB', 'CCC', 'YY', 122, 132, 33, 34 as cnt4 from dual
)
SELECT field1,
field2,
field3,
xx_stat_count AS xx,
yy_stat_count AS yy,
zz_stat_count AS zz
FROM (
SELECT field1,
field2,
field3,
my_status,
statcount
FROM dataquery
)
PIVOT (
SUM (statcount) AS stat_count
FOR (my_status) IN (
'XX' AS XX,
'YY' AS yy,
'ZZ' AS zz
)
);
输出:
FIELD1 FIELD2 XX YYZZAAA BBB CCC11 144 >33