左外连接不返回左表中的所有行?

Posted

技术标签:

【中文标题】左外连接不返回左表中的所有行?【英文标题】:Left Outer Join doesn't return all rows from my left table? 【发布时间】:2011-06-10 02:39:00 【问题描述】:

我正在尝试使用以下查询获取每天打开的页面数。

SELECT day.days, COUNT(*) as opens 
FROM day 
LEFT OUTER JOIN tracking ON day.days = DAY(FROM_UNIXTIME(open_date)) 
WHERE tracking.open_id = 10 
GROUP BY day.days

我得到的输出是这样的:

days opens
1   9
9   2

问题是,在我的日表中,我有一个包含数字 1 到 30 的列来表示一个月中的天数。我做了一个左外连接,我希望在天数列上显示所有天数!

但我的查询是这样做的,为什么会这样?

【问题讨论】:

这能回答你的问题吗? Left Join With Where Clause 【参考方案1】:

您指定连接的 tracking.open_id 必须为 10。对于其他行,它将为 NULL,因此它们不会显示!

【讨论】:

@Nanne 我觉得你搞错了+1 重要如果人们像我一样并且没有滚动过去接受的答案,下面的回复有一个更好的解释,并显示了如何获得 OP 的预期结果 以及如何解决问题【参考方案2】:

Nanne's answer given 解释了为什么你没有得到想要的结果(你的 WHERE 子句删除了行),但没有解释如何修复它。

解决方案是将 WHERE 更改为 AND,以便条件是连接条件的一部分,而不是连接后应用的过滤器:

SELECT day.days, COUNT(*) as opens 
FROM day 
LEFT OUTER JOIN tracking
ON day.days = DAY(FROM_UNIXTIME(open_date)) 
AND tracking.open_id = 10 
GROUP BY day.days

现在左表中的所有行都将出现在结果中。

【讨论】:

或者,where 子句可以更改为 WHERE (tracking.open_id IS NULL or tracking.open_id = 10),尽管我更喜欢像 mark 那样将谓词放在 join 子句中,因为我觉得在那里最有意义。 @chris: 这在连接失败时有效,但在连接成功但连接行的tracking.open_id 不等于 10 的情况下不起作用。在这种情况下,行仍将被删除。【参考方案3】:

条件在WHERE 子句中。加入表格后,将评估 WHERE 条件以过滤掉符合条件的所有内容。因此,任何不符合 tracking.open_id = 10 的内容都会被丢弃。

如果您想在连接两个表时应用此条件,更好的方法是将其与ON 子句(即连接条件)一起使用,而不是整个数据集条件。

【讨论】:

以上是关于左外连接不返回左表中的所有行?的主要内容,如果未能解决你的问题,请参考以下文章

左外连接右外连接内连接全连接的概念

每组右表的左外连接?

内连接与左外链接的区别

左外连接不返回主表中的所有记录

一张图看懂Mysql的join连接

左外连接 Microsoft excel 查询问题