获取 ROLLUP 以包含缺失值的行
Get ROLLUP to include rows for missing values
PostgreSQL 14
假设此示例数据:
fruit
ripeness
orange
1
orange
3
apple
0
apple
3
apple
3
apple
2
有没有办法让 ROLLUP 按成熟度为我提供水果数量,并为每个可能的成熟度值排成一行,如下所示:
fruit
ripeness
count
orange
0
0
orange
1
1
orange
2
0
orange
3
1
orange
2
apple
0
1
apple
1
0
apple
2
1
apple
3
2
apple
4
6
而不是像这样仅显示组中的现有值:
fruit
ripeness
count
orange
1
1
orange
3
1
orange
2
apple
0
1
apple
2
1
apple
3
2
apple
4
6
将 fruit
的不同值交叉连接到 ripeness
的不同值,并对 table.
进行 LEFT
连接
然后聚合 ROLLUP
:
SELECT f.fruit, r.ripeness,
COUNT(t.fruit) counter
FROM (SELECT DISTINCT fruit FROM tablename) f
CROSS JOIN (SELECT DISTINCT ripeness FROM tablename) r
LEFT JOIN tablename t ON t.fruit = f.fruit AND t.ripeness = r.ripeness
GROUP BY ROLLUP(f.fruit, r.ripeness)
ORDER BY f.fruit, r.ripeness;
参见demo。
没有ROLLUP
的解决方案,天真但直观:
select * from (
(
select distinct f1.fruit, f2.ripeness, (
select count(1) from fruit fsq where
f1.fruit = fsq.fruit and
f2.ripeness = fsq.ripeness
) from fruit f1
left join fruit f2 on true
group by f1.fruit, f2.ripeness
)
union
(
select fruit.fruit, null, count(1) from fruit
group by fruit.fruit
)
union
(
select null, null, count(1) from fruit
)
) mq
order by 1, 2;
Demo.
PostgreSQL 14
假设此示例数据:
fruit | ripeness |
---|---|
orange | 1 |
orange | 3 |
apple | 0 |
apple | 3 |
apple | 3 |
apple | 2 |
有没有办法让 ROLLUP 按成熟度为我提供水果数量,并为每个可能的成熟度值排成一行,如下所示:
fruit | ripeness | count |
---|---|---|
orange | 0 | 0 |
orange | 1 | 1 |
orange | 2 | 0 |
orange | 3 | 1 |
orange | 2 | |
apple | 0 | 1 |
apple | 1 | 0 |
apple | 2 | 1 |
apple | 3 | 2 |
apple | 4 | |
6 |
而不是像这样仅显示组中的现有值:
fruit | ripeness | count |
---|---|---|
orange | 1 | 1 |
orange | 3 | 1 |
orange | 2 | |
apple | 0 | 1 |
apple | 2 | 1 |
apple | 3 | 2 |
apple | 4 | |
6 |
将 fruit
的不同值交叉连接到 ripeness
的不同值,并对 table.
进行 LEFT
连接
然后聚合 ROLLUP
:
SELECT f.fruit, r.ripeness,
COUNT(t.fruit) counter
FROM (SELECT DISTINCT fruit FROM tablename) f
CROSS JOIN (SELECT DISTINCT ripeness FROM tablename) r
LEFT JOIN tablename t ON t.fruit = f.fruit AND t.ripeness = r.ripeness
GROUP BY ROLLUP(f.fruit, r.ripeness)
ORDER BY f.fruit, r.ripeness;
参见demo。
没有ROLLUP
的解决方案,天真但直观:
select * from (
(
select distinct f1.fruit, f2.ripeness, (
select count(1) from fruit fsq where
f1.fruit = fsq.fruit and
f2.ripeness = fsq.ripeness
) from fruit f1
left join fruit f2 on true
group by f1.fruit, f2.ripeness
)
union
(
select fruit.fruit, null, count(1) from fruit
group by fruit.fruit
)
union
(
select null, null, count(1) from fruit
)
) mq
order by 1, 2;
Demo.