关于 LEFT JOIN SQL 查询的 WHERE 帮助

Posted

技术标签:

【中文标题】关于 LEFT JOIN SQL 查询的 WHERE 帮助【英文标题】:Help with a WHERE on a LEFT JOIN SQL Query 【发布时间】:2010-09-18 03:45:42 【问题描述】:

我正在尝试构建一个查询,该查询将包含一列,指示用户是否已下载文档。我有一个名为 HasDownloaded 的表,其中包含以下列:id、documentID、memberID。找出用户是否下载了特定文档很容易;但我需要生成一个查询,结果如下所示:

name              id
----------------------
abc               NULL
bbb               2
ccc               53
ddd               NULL
eee               13

ID 并不重要;我感兴趣的是文档是否已下载(是否为NULL)。

这是我的查询:

SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id
WHERE HasDownloaded.memberID = @memberID

问题是,只有在 HasDownloaded 表中存在指定用户的条目时才会返回值。我想保持这个简单,并且在 HasDownloaded 中只有条目用于 已下载的文档。因此,如果用户 1 下载了 abc、bbb 和 ccc,我仍然希望 ddd 和 eee 显示在结果表中,只是 id 为 NULL。但是 WHERE 子句只为我提供了哪些条目存在的值。

我不是一个 SQL 专家 - 有没有一个操作员可以在这里给我想要的东西?我应该采取不同的方法吗?或者这是不可能的?

【问题讨论】:

【参考方案1】:

将 WHERE 子句中的条件移至连接条件。

SELECT Documents.name, HasDownloaded.id FROM Documents
LEFT JOIN HasDownloaded ON HasDownloaded.documentID = Documents.id 
  AND HasDownloaded.memberID = @memberID 

当您想在 WHERE 子句中引用左连接表时,这是必需的。

【讨论】:

太棒了!这就是我一直在寻找的。​​span> 编辑:回答了我自己的问题。我能够找到一个很好的解释为什么这是真的。 weblogs.sqlteam.com/jeffs/archive/2007/05/14/…【参考方案2】:
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId

这是正常的做法。有些人会将其缩短为:

WHERE COALESCE(HasDownloaded.memberId, @memberId) = @memberId

正如 Matt B. 所示,您可以在您的 JOIN 条件下执行此操作 - 但我认为这更有可能使人们感到困惑。如果您不明白为什么将其移至 JOIN 子句有效,那么我强烈建议您远离它。

【讨论】:

【参考方案3】:

@Mark:我理解 JOIN 语法为何有效,但感谢您的警告。我确实认为您的建议更直观。我很想知道哪个更有效。所以我进行了快速测试(恐怕这相当简单,只有 14 行和 10 次试验):

在JOIN条件下:

AND HasDownloaded.memberID = @memberID
客户端处理时间:4.6 总执行时间:35.5 服务器回复的等待时间:30.9

在 WHERE 子句中:

WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
客户端处理时间:7.7 总执行时间:27.7 服务器回复的等待时间:22.0

看起来 WHERE 子句的效率稍微高了一点。有趣的!再次感谢你们两位的帮助。

【讨论】:

以上是关于关于 LEFT JOIN SQL 查询的 WHERE 帮助的主要内容,如果未能解决你的问题,请参考以下文章

关于 LEFT JOIN SQL 查询的 WHERE 帮助

sql语句执行顺序、

如何使用 LEFT JOIN 查询将 RAW SQL 转换为 DQL

如何在 SQL 查询中对 LEFT JOIN 的顺序进行排序?

关于left join连接查询 两张表里有同名字段的问题

关于Mysql使用left join写查询语句执行很慢的问题解决