Oracle PIVOT - 未使用的列影响汇总
Oracle PIVOT - unused columns affect rollup
我有一个数据集,其中包含几个关键字段、一个状态和一个计数。 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
这是预期的行为吗?
我可以解决这个问题,方法是预先添加一个子查询 select 只是要由 PIVOT 处理的 field1、field2、field3、mystatus 和 statcount,或者执行 select /之后分组,得到卷起来。
Is this expected behavior?
是的,来自 SELECT
documentation:
The pivot_clause
computes the aggregation functions specified at the beginning of the clause. Aggregation functions must specify a GROUP BY
clause to return multiple values, yet the pivot_clause
does not contain an explicit GROUP BY
clause. Instead, the pivot_clause
performs an implicit GROUP BY
. The implicit grouping is based on all the columns not referred to in the pivot_clause
, along with the set of values specified in the pivot_in_clause
.). If you specify more than one aggregation function, then you must provide aliases for at least all but one of the aggregation functions.
要解决它,请使用子查询仅 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
FIELD3
XX
YY
ZZ
AAA
BBB
CCC
11
144
33
db<>fiddle here
我有一个数据集,其中包含几个关键字段、一个状态和一个计数。 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
这是预期的行为吗?
我可以解决这个问题,方法是预先添加一个子查询 select 只是要由 PIVOT 处理的 field1、field2、field3、mystatus 和 statcount,或者执行 select /之后分组,得到卷起来。
Is this expected behavior?
是的,来自 SELECT
documentation:
The
pivot_clause
computes the aggregation functions specified at the beginning of the clause. Aggregation functions must specify aGROUP BY
clause to return multiple values, yet thepivot_clause
does not contain an explicitGROUP BY
clause. Instead, thepivot_clause
performs an implicitGROUP BY
. The implicit grouping is based on all the columns not referred to in thepivot_clause
, along with the set of values specified in thepivot_in_clause
.). If you specify more than one aggregation function, then you must provide aliases for at least all but one of the aggregation functions.
要解决它,请使用子查询仅 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 FIELD3 XX YY ZZ AAA BBB CCC 11 144 33
db<>fiddle here