SQL LEFT JOIN 与返回 NULL 值的 COUNT
Posted
技术标签:
【中文标题】SQL LEFT JOIN 与返回 NULL 值的 COUNT【英文标题】:SQL LEFT JOIN with COUNT that returns NULL values 【发布时间】:2017-10-05 11:04:51 【问题描述】:我有两个表:一个存储产品 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 的销售总额时,我应该修改什么以获得每个月的一行?谢谢
【问题讨论】:
我建议你看看日历表。 考虑处理表示层/应用程序级代码中的数据显示问题,假设您有(例如,作用于有序数组的简单 php 循环)。 没有销售,因此没有转换为月份的日期:因此您必须提供缺少的月份 【参考方案1】:使用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
中。我应该指出,您可以使用其他日期来源(如果有的话),或者明确列出它们。
【讨论】:
如果销售数据非常大,“从销售中选择不同的销售日期”可能会很慢,替代方法可能是使用日期表(“日历表”)。 非常感谢你们两位,交叉连接是正确的方向。出于性能原因,我还创建了一个单独的日历表。 我还为性能测试创建了一个单独的日历表:执行时间增加了 40%(销售表有超过 200 万行)。【参考方案2】:你能试试这个查询吗:
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
【讨论】:
以上是关于SQL LEFT JOIN 与返回 NULL 值的 COUNT的主要内容,如果未能解决你的问题,请参考以下文章
Spark SQL中Dataframe join操作含null值的列
SQL中left join on 、right join on、inner join on之间的区别
SQL Server-聚焦LEFT JOIN...IS NULL AND NOT EXISTS性能分析(十七)
sql中 INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN 中 ON与Where的区别
sql中 INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN 中 ON与Where的区别