【问题标题】:How to Join Three Tables with Count Function to Return Zero Results Too?如何使用计数函数连接三个表以返回零结果?
【发布时间】:2015-02-08 20:55:10
【问题描述】:

我有这个查询,有三个表(发票,客户地址,国家),我想返回每个国家的销售数量,有些国家没有销售,所以我想返回零作为销售计数而不是排除他们从结果中。

SELECT c.name,c.iso_code,c.id as country_id, COUNT(*) as sales_count ,SUM(a.total_due) as gross
        FROM `invoices` a
            JOIN `customer_addresses` b
            ON b.`customer_id` = a.`customer_id`
            JOIN `countries` c
            ON c.`id` = b.`country_id`
        WHERE  a.`status` = 'Paid' AND a.`deleted` ='No'
        GROUP BY c.name

样本数据:

发票

id   | total_due | customer_id
1    |    25     |      5
2    |    45     |      7

客户地址

id |    address    | customer_id | country_id
5  |  some address | 1           |    3
7  |  some address | 2           |    4

国家

id |       name     | iso_code 
3  | USA            | US
4  | United Kingdom | UK
5  | France         | Fr

【问题讨论】:

  • 在询问 sql 查询问题时包含示例数据和所需结果总是明智的。是否应将地址位于多个国家/地区的客户的销售额计入每个国家/地区?
  • @popovitsj 我添加了示例数据,您可以看到“France”在“customer_addresses”表中没有引用,所以我的查询没有返回结果,我也想包括 France , sales_count = 0

标签: mysql sql join inner-join


【解决方案1】:

您可以使用right join 代替(inner) join,但它的使用并不多,而且通常被认为可读性差。

因此,您可以将left join 用于表格并将country 设为第一个表格。使用left join,即使连接表中没有匹配的行,您仍然可以获得结果。对count 的调用也略有改变。 count(*) 将仅返回行数,因此对于没有发票的国家/地区,它将返回 1count(invoice_id) 仅计算 invoice_id is not null 所在的行,因此对于没有销售的国家/地区,将返回 0

SELECT 
  c.name, c.iso_code, c.id as country_id, 
  COUNT(a.invoice_id) as sales_count,
  SUM(a.total_due) as gross
FROM 
  `countries` c
  LEFT JOIN `customer_addresses` b
    ON c.`id` = b.`country_id`
  LEFT JOIN `invoices` a
    ON b.`customer_id` = a.`customer_id`
    AND a.`status` = 'Paid' 
    AND a.`deleted` ='No'
GROUP BY c.name

【讨论】:

  • 我刚试了一下,可惜没用,还没有返回零销量的国家。
  • 你是对的。我犯了一个愚蠢的错误。 WHERE 子句中的条件也应该在联接中,否则这些国家/地区仍将被排除在外。我现在修复了查询。
猜你喜欢
  • 2017-10-30
  • 1970-01-01
  • 2019-05-17
  • 2014-10-09
  • 2019-02-08
  • 1970-01-01
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
相关资源
最近更新 更多