左外连接不返回左表中的所有行?
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
子句(即连接条件)一起使用,而不是整个数据集条件。
【讨论】:
以上是关于左外连接不返回左表中的所有行?的主要内容,如果未能解决你的问题,请参考以下文章