LEFT JOIN 无法替换 NOT EXISTS MYSQL

LEFT JOIN not working to replace a NOT EXISTS MYSQL

我有一个名为 Documents 的 table 和一个名为 Notes 的 table 用于存储文档的注释。我需要获取所有没有状态为 2 或 3 的注释的文档。

SELECT * FROM Documents 
   WHERE NOT EXISTS (
      SELECT docID FROM Notes WHERE docId = id AND status IN (2, 3)
   )

这非常慢,但可以。我尝试进行内部连接,但如果只有一张纸条的状态不是 2 或 3,它仍会显示文档。我需要它只显示在任何注释中都没有出现 2 或 3 的文档。

谁能帮忙!?谢谢!

一种方法:

SELECT *, COUNT(docID)
FROM Documents
LEFT JOIN Notes ON docID = id AND (status IN (2,3))
GROUP BY id
HAVING COUNT(docID) = 0

如果 status=2 或 status=3,则计数将为非零,并且 having 将完全消除文档。

反加入 是一种熟悉的 SQL 模式。

使用该模式,我们使用外连接操作 return 所有行,以及匹配的行,包括 没有匹配的行。 "trick" 是在 WHERE 子句中使用谓词来过滤掉所有找到匹配的行,只留下没有匹配的行。

例如,要从 Documents 中检索在 Notes 中没有任何符合指定条件的匹配行的行:

SELECT d.* 
  FROM Documents d
  LEFT
  JOIN Notes n
    ON n.docId = d.id
   AND n.status IN (2,3)
 WHERE n.docId IS NULL

(我猜测 docIdstatus 是对 Notes 中列的引用,而 id 是对 [=11 中列的引用=]。您的查询中的列引用没有限定,因此我们只能猜测哪些列在 table 中。最佳做法是在引用多个 table 的查询中限定所有列引用]。一个很大的好处是它可以在不查看 table 定义的情况下破译语句,找出哪些列来自哪些 table。)

该查询将从 Documents 中的 return 行,其中在 Notes 中没有任何 "matching" 状态为 23 的行.

因为 LEFT JOIN 是外连接,它 returns all 来自 Documents 的行,以及来自 Notes 的匹配行. Documents 中没有匹配行的任何行也将被 returned,Notes 中的列的值为 NULL。连接中的相等谓词 (n.docId = d.Id) 向我们保证任何 "matching" 行都将具有 docId.

的非 NULL 值

"trick" 是 WHERE 子句中的谓词:n.docId IS NULL

任何匹配的行都将被过滤掉,所以我们只剩下 Documents 中没有匹配的行。


原查询有status NOT IN (2,3)。这基本上会忽略 Notes 中具有其中一种状态的行,并且只有具有其他非 NULL 状态值的行会 "match"。根据规范... "no notes with a status of 2 or 3",这似乎暗示您希望在查询中使用 status IN (2,3)