On Sep 4, 2012, at 11:59 AM, Martin Crouch wrote:
Quote:
Given the following two tables:
Table: pets With one column pet_type with rows containing the values:
Dog, Cat, Bird, Fish
Then another table pet_owners with two colums pet_owner and pet_type
both strings.
I want to find the pet_owners who do not have a full set of pets as
defined in the pets table, and which ones they are missing. |
Well, as long as the row counts remain reasonable, you can do:
select cp.pet_owner, cp.pet_type
from (select dpo.pet_owner, dpp.pet_type
from (select distinct pet_owner from pet_owners) dp, pets dpp) cp
left join pet_owners pown on cp.pet_owner = pown.pet_owner and cp.pet_type=pown.pet_type
where pown.tid is null;
which constructs the cross product of (distinct) pet owners and pet types,
and finds the ones that aren't in the actual pet owner table. The left join / tid
is null business is just another way of writing a not exists and you can do
it with not exists if you like.
If the exceptions will be relatively rare, you can help the server do less work
by replacing the (select distinct pet_owner from pet_owners)
with (select pet_owner from pet_owners group by pet_owner
having count(*) < (select count(*) from pets))
I haven't tried any of this but it ought to be close enough to get the
idea across, I hope.
Karl