I have 2 simple mysql tables. The first 1 called mail and has 2 rows:
sender | receiver
Marley | Bob
Saget | Bob
The second one called block and has 1 row:
blocker | blocked
Bob | Marley
I want to select sender(s) from the first table who sent Bob emails but aren't blocked in the block table. So the results should be:
sender
saget
I tried the following query but it's not returning results:
SELECT * FROM mail
LEFT JOIN block ON (block.blocker = 'Bob')
WHERE (block.blocked <> mail.sender)
That's why the best way to search for missing values in MySQL is using a LEFT JOIN / IS NULL or NOT IN rather than NOT EXISTS .
The SQL LEFT JOIN returns all rows from the left table, even if there are no matches in the right table. This means that if the ON clause matches 0 (zero) records in the right table; the join will still return a row in the result, but with NULL in each column from the right table.
Many years ago (SQL Server 6.0 ish), LEFT JOIN was quicker, but that hasn't been the case for a very long time. These days, NOT EXISTS is marginally faster. The biggest impact in Access is that the JOIN method has to complete the join before filtering it, constructing the joined set in memory.
Left joins can increase the number of rows in the left table if there are multiple matches in the right table.
The left join will produce null
rows for the mismatches.
It's those null
rows that you need to filter on.
SELECT * FROM mail
LEFT JOIN block ON (block.blocker = 'Bob')
WHERE block.blocker IS NULL
It's kind of strangle to be joining on a fixed value however, a more common join (given your tables) would be:
SELECT * FROM mail
LEFT JOIN block ON (block.blocker = mail.receiver
and block.blocked = mail.sender)<<-- these should match
WHERE block.blocker IS NULL <<-- select only mismatches
AND mail.receiver like 'bob';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With