我有两张桌子,一张叫做“关键词”;此表只是将关键字存储为唯一关键字ID和关键字的文本。另一个叫做“keylinks”;此表存储将媒体ID链接到关键字ID的行。
如果我有一个媒体项目,并且我想获得该媒体项目的所有关键字,我会使用以下代码:
SELECT keywords.*, keylinks.*
FROM keywords
LEFT JOIN keylinks ON (keylinks.keyword_id = keywords.keyword_id)
WHERE keylinks.media_id = ?
如果我想做相反的事情怎么办?
我想获得与媒体ID不匹配的关键字,而不是获取与媒体ID匹配的关键字。我该怎么做?我不能简单地使用WHERE keylinks.media_id != ?
,因为这会返回数千行与特定媒体ID无关的keylink条目,这些条目实际上可能是匹配的关键字。
答案 0 :(得分:2)
SELECT K1.keyword_id
FROM keywords AS K1
WHERE
NOT EXISTS (SELECT *
FROM keylinks AS K2
WHERE K2.keyword_id = K1.keyword_id
AND K2.media_id = %d);
这将为您提供数据库中没有keylink的所有关键字。
答案 1 :(得分:2)
至少有三种方法可以做到这一点。 ANSI提供EXCEPT
,目前似乎不支持MySQL。
使用OUTER JOIN放置标准至关重要 - 如果在WHERE子句中,则在 JOIN之后应用标准。如果条件在JOIN中,则在 JOIN之前应用。
SELECT k.*
FROM KEYWORDS k
LEFT JOIN KEYLINKS kl ON kl.keyword_id = k.keyword_id
AND.media_id = ?
WHERE keylinks.media_id IS NULL
SELECT k.*
FROM KEYWORDS k
WHERE NOT EXISTS (SELECT NULL
FROM KEYLINKS kl
WHERE kl.keyword_id = k.keyword_id
AND kl.media_id = ?)
SELECT k.*
FROM KEYWORDS k
WHERE k.keyword_id NOT IN (SELECT kl.keyword_id
FROM KEYLINKS kl
WHERE kl.media_id = ?)
这取决于比较的列是否可以为空(值可以是NULL
)。
LEFT JOIN / IS NULL
最快意味着 仅适用于MySQL 。 NOT EXISTS
/NOT IN
are the most efficient。