I have 3 tables:
Table columns
---------------------
items id, name
variations id, item_id
images id, variation_id, type
image
has a variation
and variation
has an item
I want to find items
which don't have images
of type 4 or 5 (types are any integer 0..5 and cannot be null)
The below query works however it makes use of a UNION subquery with a NOT IN constraint which I believe is inefficient - the question is therefore what is a more efficient way to write this query.
SELECT DISTINCT i.id, i.name
FROM items i
INNER JOIN variations v
ON v.item_id = i.id
INNER JOIN images vi
ON vi.variation_id = v.id
WHERE i.id NOT IN (SELECT i.id FROM items i
INNER JOIN variations v
ON v.item_id = i.id
INNER JOIN images vi
ON vi.variation_id = v.id
WHERE vi.type = 4
UNION
SELECT i.id FROM items i
INNER JOIN variations v
ON v.item_id = i.id
INNER JOIN images vi
ON vi.variation_id = v.id
WHERE vi.type = 5)
Solution
Based on Gordons answer below final solution is:
select i.*
from items i
where not exists (select 1
from variations v join
images im
on v.image_id = im.id
where v.item_id = i.item_id and i.type in (4, 5)
)
and exists (select 1
from variations v join
images im
on v.id = im.variation_id
where v.item_id = i.id)
I want to find items which don't have images of type 4 or 5
Based on your description, this sounds like not exists
:
select i.*
from items i
where not exists (select 1
from variations v join
images im
on v.image_id = im.id
where v.item_id = i.item_id and i.type in (4, 5)
);