I have two tables, one is called “keywords”; this table simply stores keywords as a unique keyword ID, and the text of the keyword. The other is called “keylinks”; this table stores rows linking a media ID to a keyword ID.
If I had a media item, and I wanted to get all the keywords for that media item, I would use the following code:
SELECT keywords.*, keylinks.*
FROM keywords
LEFT JOIN keylinks ON (keylinks.keyword_id = keywords.keyword_id)
WHERE keylinks.media_id = ?
What if I wanted to do the opposite?
Instead of getting the keywords that match a media ID, I would like to get the keywords that DON’T match a media ID. How would I do this? I cant simply use WHERE keylinks.media_id != ? because that would return thousands of rows of keylink entries that don’t relate to that specific media ID, which may in fact be matching keywords.
There’s at least three means of doing this. ANSI provides
EXCEPT, which doesn’t appear to be supported by MySQL at this time.LEFT JOIN/IS NULL
The placement of criteria with an OUTER JOIN is crucial – if in the WHERE clause, the criteria is applied after the JOIN. If the criteria is in the JOIN, the criteria is applied before the JOIN.
NOT EXISTS
NOT IN
Which Performs Best?
It depends on if the columns compared can be nullable (the value could be
NULL) or not.LEFT JOIN / IS NULLis the fastest means on MySQL only.NOT EXISTS/NOT INare the most efficient.