24

我正在尝试构建一个查询,该查询将包含一个指示用户是否已下载文档的列。我有一个名为 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 专家 - 有没有一个操作员可以在这里给我我想要的东西?我应该采取不同的方法吗?或者这是不可能的?

4

3 回答 3

43

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

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

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

于 2008-10-20T16:27:46.473 回答
4
WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId

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

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

You can, as Matt B. shows, do it in your JOIN condition - but I think that's much more likely to confuse folks. If you don't understand WHY moving it to the JOIN clause works, then I'd strongly suggest staying away from it.

于 2008-10-20T16:58:10.107 回答
3

@Mark: I understand why the JOIN syntax works, but thanks for the warning. I do think your suggestion is more intuitive. I was curious to see which was more efficient. So I ran a quick test (this was rather simplistic, I'm afraid, over only 14 rows and 10 trials):

In the JOIN condition:

AND HasDownloaded.memberID = @memberID
  • Client processing time: 4.6
  • Total execution time: 35.5
  • Wait time on server replies: 30.9

In the WHERE clause:

WHERE HasDownloaded.memberId IS NULL OR HasDownloaded.memberId = @memberId
  • Client processing time: 7.7
  • Total execution time: 27.7
  • Wait time on server replies: 22.0

It looks like the WHERE clause is ever-so-slightly more efficient. Interesting! Once again, thanks to both of you for your help.

于 2008-10-20T17:46:11.743 回答