获取 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.