Reputation: 1145
It is difficult to explain what I want in the title, some I'll try to do it with an example here. I have 2 tables:
[Table1]
set_id | data
-------+-----
1 | 123
2 | 456
3 | 789
4 | 987
[Table2]
set_id | single_id
-------+----------
1 | 10
2 | 10
2 | 13
3 | 10
3 | 13
3 | 14
4 | 10
4 | 15
I need to select row in Table1
with such set_id
that in Table2
rows with same set_id
have single_id
s only those given in query. For example:
For query (10, 13)
resulting row should be 2 | 456
.
For query (10)
resulting row should be 1 | 123
.
For query (10, 13, 14)
resulting row should be 3 | 789
.
How this can be done?
Upvotes: 0
Views: 284
Reputation: 1269443
This is an example of a set-within-sets
subquery. I think the most general approach is to use aggregation with a having
clause:
select t1.set_id, t1.data
from table1 t1 join
table2 t2
on t1.set_id = t2.set_id
group by t1.set_id
having sum(t2.single_id = 10) > 0 and
sum(t2.single_id = 13) > 0 and
sum(t2.single_id not in (10, 13)) = 0;
Each condition in the having
clause tests one condition. The first is that a row with 10
is present; the second that a row with 13
is present. And the last that no other values are present.
EDIT:
In MySQL, there is actually another approach which might seem more intuitive:
select t1.set_id, t1.data
from table1 t1 join
table2 t2
on t1.set_id = t2.set_id
group by t1.set_id
having group_concat(distinct t2.single_id order by t2.single_id) = '10,13';
That is, concatenate the distinct values together, in order, and compare them to a constant string.
Upvotes: 2