【问题标题】:Insert missing rows (with zero values) into table, following a display pattern按照显示模式将缺失的行(零值)插入表中
【发布时间】:2025-12-28 09:45:17
【问题描述】:

我正在创建一个循环遍历下表以创建报告的过程:

INSERT INTO temp_data
SELECT val_year, val_name, Group_A, Group_B, Group_C, SUM(product_count) AS in_stock
FROM all_products
GROUP BY val_year, val_name, Group_A, Group_B, Group_C;

Resulting rows:
1: 2014, product_a, food, hot, delicious, 50
2: 2014, product_a, food, hot, fast, 30
3: 2014, product_a, food, cold, delicious, 10
4: 2014, product_a, drinks, hot, delicious, 20
5: 2014, product_a, drinks, cold, delicious, 40
6: 2014, product_a, drinks, cold, fast, 60

7: 2014, product_b, food, hot, delicious, 70
... etc.

表 all_products 之前已通过各种 UNION ALL 查询等创建。

我现在需要将这些结果报告给我的上级,但该表看起来有“缺失”值。我需要重建该表,以便它显示缺失值为零的组。

我需要以某种模式显示所有值,这个例子就是我想要的显示:

Rows:
1: 2014, product_a, food, hot, delicious, 50
2: 2014, product_a, food, hot, fast, 30
3: 2014, product_a, food, cold, delicious, 10
4: 2014, product_a, food, cold, fast, 0
5: 2014, product_a, drinks, hot, delicious, 20
6: 2014, product_a, drinks, hot, fast, 0
7: 2014, product_a, drinks, cold, delicious, 40
8: 2014, product_a, drinks, cold, fast, 60

9: 2014, product_b, food, hot, delicious, 70
... etc.

注意第 4 行和第 6 行已填充,以显示无库存产品的零值。

是否有任何简单(快速)的方法来填充缺失的行?我能想到的只是一个巨大的 200 多行 FOR LOOP,它遍历当前组,检查组更改并在组更改时附加缺失的组。这种方法感觉有点不专业。

【问题讨论】:

    标签: sql oracle plsql


    【解决方案1】:

    您可以通过首先生成所有行(使用cross join)然后引入值来做到这一点:

    select y.val_year, g.val_name, g.Group_A, g.Group_B, g.Group_C,
           coalesce(in_stock, 0) as in_stock
    from (select distinct val_year from temp_data) y cross join
         (select distinct val_name, Group_A, Group_B, Group_C from temp_data) g left join
         temp_data d
         on d.val_year = y.val_year and
            d.val_name = g.val_name and
            d.Group_A = g.Group_A and
            d.Group_B = g.Group_B and
            d.Group_C = g.Group_C;
    

    您也可以直接在all_products 上执行此操作。例如,您可以将 CTE 添加到上述查询中:

    with temp_data as (
          SELECT val_year, val_name, Group_A, Group_B, Group_C, SUM(product_count) AS in_stock
          FROM all_products
          GROUP BY val_year, val_name, Group_A, Group_B, Group_C
         )
    

    【讨论】: