Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MYSQL - Select only if row in LEFT JOIN is not present

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)
like image 733
Michael Samuel Avatar asked Mar 20 '13 19:03

Michael Samuel


People also ask

Which join is not present in MySQL?

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 .

WHAT IF LEFT join is null?

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.

Which is faster not in or left join?

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.

Does LEFT join change number of rows?

Left joins can increase the number of rows in the left table if there are multiple matches in the right table.


1 Answers

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';
like image 163
Johan Avatar answered Sep 17 '22 12:09

Johan