【问题标题】:How to include zero results when querying one single table?查询一个表时如何包含零结果?
【发布时间】:2016-07-11 17:34:11
【问题描述】:

我有一个名为 Apartments 的表,它包含三列:apartment_type、person、date。它包括由某个人和日期选择的公寓类型。我需要计算有多少人选择了每种公寓类型。一些公寓类型的人口为 0。

这是我的查询:

SELECT apartment_type, COUNT(*) AS TOTAL
FROM  Apartments
GROUP BY apartment_type

效果很好,但它不包括值为 0 的公寓类型。请帮我更正此查询。

【问题讨论】:

  • 您有一张表格,上面列出了所有可能的公寓类型吗?
  • 看来该表将使用 apartment_type 作为引用另一个表的外键,例如APARTMENT_TYPE。到目前为止,按照您解释此问题的方式,您将无法获得预期的结果。
  • 顺便说一句,如果您指定您正在使用的数据库会很好。

标签: sql


【解决方案1】:

如果某些 appartment_type 的人口为 0 - 您的表将不包含该类型的任何记录 - 因此您必须从另一个表添加一些连接,其中所有公寓类型都存在。或者使用 union 创建所有 0 个填充条目。

类似:

SELECT apartment_type, COUNT(*) AS TOTAL
FROM  (SELECT * FROM Apartments UNION ALL SELECT apartment_type, 0 as person, 0 as date from SomeTableWithFullListOfTypes group by apartment_type) as tmp
GROUP BY apartment_type

【讨论】:

  • 好吧,假设我有第二个表 Apartment_type 列出所有可能的公寓类型,以及 Apartment 表列出所有人员和他们选择的公寓类型。外键是“公寓类型”。我需要列出所有公寓类型及其人口,即使它是 0。我应该如何加入这些表以使其工作?
  • 您回答的文本部分很好,但您发布的查询看起来不正确。如果有的话,通过这样做union all,它会弄乱外部查询中的count(*)。你想要的是一个简单的left join
  • 是的,我刚刚更新了查询 - 添加了 group by 以便在 union 中进行第二次选择
  • 这里不需要联合,你需要像@sstan 说的那样加入。
【解决方案2】:

我一般同意 Nosyara 的回答,但我不同意他对union all 的示例查询。我不确定它是否有效,而且它肯定太复杂了。

如前所述,如果您没有包含所有可能公寓类型的表格,请创建一个。然后您可以使用简单的left join 编写查询:

select t.apartment_type, count(a.apartment_type) as total
  from apartment_types t
  left join apartments a
    on a.apartment_type = t.apartment_type
 group by t.apartment_type

注意count(*) 是如何被count(a.apartment_type) 替换的。在您没有特定公寓类型的公寓的情况下,该更改对于准确计算是必要的。

【讨论】:

  • 谢谢! t 和 a 代表什么?
  • 他们是别名。在这种情况下,tapartment_types 的别名,aapartments 的别名。在编写连接时,您通常需要通过在表名前面加上前缀来指定列来自特定表。通过定义别名,您可以在限定列名时键入较短的别名而不是完整的表名。
  • 所以 t.apartment_type 是来自 apartment_types 表的 apartment_type 列,a.apartment_type 是来自 apartments 表的 apartment_type 列。对吗?
  • 您的查询与 Andrew 下面发布的查询有什么区别?
  • 我可以说:SELECT apartment_type, COUNT(Apartments.apartment_type) AS TOTAL FROM Apartment_types LEFT JOIN Apartments ON Apartments.apartment_type = Apartment_types.apartment_type GROUP BY apartment_type
【解决方案3】:
SELECT apartment_type, COUNT(apartment.*) AS TOTAL
FROM  apartment_type 
left join apartment
on  apartment_type.aparentment_type = apartements.apartment_type
GROUP BY apartment_type

使用左连接将为您提供连接左侧的所有内容(因此您的所有类型)以及右侧匹配的所有内容。

【讨论】:

  • 非常感谢。请澄清它是否应该是 COUNT(apartment.apartment_type) 而不是 COUNT(apartment.*)。我认为应该是:SELECT apartment_type, COUNT(Apartments.apartment_type) AS TOTAL FROM Apartment_types LEFT JOIN Apartments ON Apartments.apartment_type = Apartment_types.apartment_type GROUP BY apartment_type 请检查
  • count(apartment.apartment_type) 将返回与count(apartment.*) 相同的值。它只是计算每一行。
猜你喜欢
  • 2017-12-11
  • 1970-01-01
  • 2020-07-19
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
相关资源
最近更新 更多