views:

34

answers:

3

I have 2 tables... meat and potatoes in MySQL.

meat_id is the primary key for the meat table and there is a meat_id in the potatoes table that links the 2 tables. I want to find all rows in the potatoes table that don't have a valid meat_id. Any ideas?

+2  A: 
 SELECT *
 FROM potatoes p
 WHERE NOT EXISTS (SELECT 1 from meat m where m.meat_id = p.meat_id)
Michael Pakhantsov
+4  A: 

Using LEFT JOIN/IS NULL:

   SELECT p.*
     FROM POTATOES p
LEFT JOIN MEAT m ON m.meat_id = p.meat_id
    WHERE m.meat_id IS NULL

Using NOT EXISTS:

SELECT p.*
  FROM POTATOES p
 WHERE NOT EXISTS(SELECT NULL
                    FROM MEAT m
                   WHERE m.meat_id = p.meat_id)

Using NOT IN:

SELECT p.*
  FROM POTATOES p
 WHERE p.meat_id NOT IN (SELECT m.meat_id
                           FROM MEAT m)

Summary

LEFT JOIN/IS NULL is the best performing option if the column(s) compared in the join can not be NULL. If those values can be NULL, then NOT EXISTS or NOT IN perform best.

OMG Ponies
I don't think this will work with a WHERE clause because the constraint is executed before the JOIN. Look at my answer, it uses `HAVING` instead.
SchlaWiener
@ShlaWiener: See the links I posted - MySQL is the only DB (of the major ones) where LEFT JOIN/IS NULL is the best performer (**only** when the columns compared in the join are **not** nullable).
OMG Ponies
Interesting, I always believed that mysql will look at the actual values from the db but I just verified that `WHERE` works. Using `HAVING` leads to the same result but can't perform better than where.
SchlaWiener
A: 

Do a left join and use having:

SELECT p.potato_id, m.meat_id
FROM potatos p
LEFT JOIN meat m ON p.meat_id = m.meat_id
HAVING m.meat_id IS null
SchlaWiener
`HAVING` is only necessary if you're using aggregate functions - which your answer doesn't. That's because the `HAVING` clause is equivalent to the WHERE, but the difference is that WHERE can not have aggregate functions (in subqueries is OK) while HAVING can.
OMG Ponies