Reputation: 8308
I am trying to write a query for MySQL that selects all parents where there are child records for every condition. My schema is more complicated than this but this is the idea.
For example:
id, ....
parent_id, id, key, value
So,
SELECT pt.id FROM parent_table pt
JOIN child_table ct ON pt.id = ct.parent_id
WHERE **AllOfTheseExist** (ct.key = "keyName1" AND ct.value = "value1")
AND (ct.key = "keyName2" AND ct.value = "value2")
If I 'or' them together it works great but I need it to be exclusive, not inclusive.
Upvotes: 1
Views: 347
Reputation: 62851
The problem with your query is ct.key cannot equal both keyname1 and keyname2 in the same row. You either need to check the child table multiple times or use conditional aggregation. Here's one option using exists
:
SELECT id
FROM parent_table pt
WHERE EXISTS (
SELECT 1
FROM child_table ct
WHERE pt.id = ct.parent_id
AND ct.key = 'keyName1'
AND ct.value = 'value1') AND EXISTS (
SELECT 1
FROM child_table ct
WHERE pt.id = ct.parent_id
ct.key = 'keyName2' AND
ct.value = 'value2')
Or you could use conditional aggregation:
select id
from parent_table pt
where exists (
select 1
from child_table ct
where pt.id = ct.parent_id
group by ct.parent_id
having sum(case when ct.key = 'keyname1' and ct.value = 'value1'
then 1 else 0 end) > 0 and
sum(case when ct.key = 'keyname2' and ct.value = 'value2'
then 1 else 0 end) > 0 )
Maybe one other option using distinct
with multiple joins
:
select distinct pt.id
from parent_table pt
join child_table ct1 on pt.id = ct1.parent_id and
ct1.key = 'keyname1' and
ct1.value = 'value1'
join child_table ct2 on pt.id = ct2.parent_id and
ct2.key = 'keyname1' and
ct2.value = 'value1'
Upvotes: 1