SQL LEFT JOIN与COUNT一起返回NULL值

时间:2017-10-05 11:04:52

标签: mysql sql

我有两个表:一个存储产品ID,另一个存储每个product_id和每个sale_date的总销售额

表产品

product_id
----------
1         
2         
3         

表销售

product_id |  sale_date | total
-----------+------------+-------
1          | 2017-01-01 |   1
1          | 2017-02-01 |   1
1          | 2017-03-01 |   1

产品2和产品3没有销售总额。

我想查询销售表,以便在没有任何产品ID销售的月份前获得0。 我想要实现的结果是:

product_id |  month     | total
-----------+------------+-------
1          | 2017-01    |   1
1          | 2017-02    |   1
1          | 2017-03    |   1
2          | 2017-01    |   0
2          | 2017-02    |   0
2          | 2017-03    |   0
3          | 2017-01    |   0
3          | 2017-02    |   0
3          | 2017-03    |   0

现在我做的是:

SELECT DATE_FORMAT(sale_date, "%m-%Y") as month,
       Products.product_id,
       COUNT(Sales.product_id) as total 

  FROM products Products 

LEFT OUTER JOIN sales Sales

             ON Sales.product_id = Products.product_id 

       GROUP BY Products.product_id, month

我得到的是:

product_id |  month     | total
-----------+------------+-------
1          | 2017-01    |   1
1          | 2017-02    |   1
1          | 2017-03    |   1
2          | NULL       |   0
3          | NULL       |   0

如果任何产品ID没有销售总额,我应该修改哪个每个月获得一行?谢谢

2 个答案:

答案 0 :(得分:4)

使用cross join生成行,然后使用left in来生成值:

select p.product_id, d.sales_date,
       coalesce(s.total, 0) as total
from products p cross join
     (select distinct sales_date from sales) d left join
     sales s
     on s.product_id = p.product_id and s.sales_date = d.sales_date
order by p.product_id, d.sales_date;

注意:这假定您想要的所有日期都在sales。我应该指出,如果您有日期,可以使用其他来源,或明确列出日期。

答案 1 :(得分:0)

您可以尝试一下这个查询:

select 
 distinct p.product_id, 
 DATE_FORMAT(sale_date, "%m-%Y") as month,
 if(p.product_id <> s.product_id, 0,total) as total 
 from products p, 
sales s 
order by p.product_id