繁体   English   中英

如何加入 SQL 表并包括缺失的行?

[英]How to join SQL tables and include missing rows?

假设您有一张表meal_types ,如下所示:

meal_type_id  |  type
--------------|------------
     1        |  breakfast
     2        |  lunch
     3        |  dinner

第二张桌子叫做meals

meal_id  |  food    |  meal_type_id
---------|----------|------
   1     |  bacon   |   1
   2     |  eggs    |   1
   3     |  fries   |   2
   4     |  burger  |   2
   5     |  soup    |   3

第三个表称为meal_counts

external_id | count | meal_id
------------|-------|---------
    1       |  100  |   3
    2       |  50   |   5
    2       |  25   |   3
    3       |  15   |   2

预期 output

返回按 meal_type_id 分组的每个 external_id 的总计数。 每个 external_id 都必须出现所有 meal_type_id 值。 如果 external_id 不包含 meal_type_id,则其计数必须设置为 0。

 external_id | count | meal_type_id
 ------------|-------|-------------
     1       |  0    |   1
     1       |  100  |   2
     1       |  0    |   3
     2       |  0    |   1
     2       |  25   |   2
     2       |  50   |   3
     3       |  15   |   1
     3       |  0    |   2
     3       |  0    |   3

请注意,即使 external_id = 1 没有早餐 (1) 和午餐 (2) 类型的餐食计数,它们仍会添加到结果中,并且它们的计数设置为 0。

我在这方面的工作

SELECT external_id, SUM(count) as total, meal_type_id
FROM meal_counts
INNER JOIN meals ON meal_counts.meal_id = meals.meal_id
INNER JOIN meal_types ON meal_types.meal_type_id = meals.meal_type_id
GROUP BY external_id, meal_type_id

这种方法的问题是,如果 external_id 不包含meal_type_id,它将不会返回所有meal_types。

我怎样才能用一个查询来解决这个问题?

谢谢你。

您可以使用交叉连接,它为您提供 meal_counts 表中所有可能的 meal_type 组合:

select 
   external_id 
  ,mt.meal_type_id 
  ,coalesce(max(counter) filter (where mt.meal_type_id = m.meal_type_id),0) counter
from meal_counts mc
join meals m
  on m.meal_id = mc.meal_id
cross join meal_types mt 
group by external_id, mt.meal_type_id
order by external_id, mt.meal_type_id

如果我理解正确,您可以使用获取external_id的派生表,将其与meal_counts交叉连接,将其与meal_types左连接并使用coalesce()来获取0count ,其中没有找到提供count的连接伙伴.

SELECT mc2.external_id,
       coalesce(mc3.count, 0) count,
       mt1.meal_type_id
       FROM (SELECT DISTINCT
                    mc1.external_id
                    FROM meal_counts mc1) mc2
            CROSS JOIN meal_types mt1
            LEFT JOIN meal_counts mc3
                      ON mc3.external_id = mc2.external_id;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM