简体   繁体   中英

Only return if main query has all the rows that subquery returns

I want to write a query that would return data if and only if it has all the ids that the subquery would return

What I've tried:

SELECT * FROM main_table WHERE id IN ( SELECT id FROM sub_table WHERE SOMECODITION)

but it returns once it finds at least one matching row in sub query which i do not want.

Mainly I wanna be able to check if the main_table has all the ids that sub_table returns

EDIT:

the SOMECONDITION has nothing to do with main query

You can achieve that by using left join as well. Like for instance, let's take a small example main_table has ids 1,2,3 and sub_table has ids 1,2,5,6 (that matches SOMECONDITION ) so the following query,

select s.id sid,m.id mid from 
sub_table s left join main_table m on s.id = m.id where s.SOMECONDITION

would result in:

sid     mid
1       1
2       2
5       null
6       null

In this case main table does not have all the IDs that the sub query returns. You can make use of count to fetch results only if the count(sid) equals count(mid) , since count doesn't consider null values. So your query would become.

SELECT * FROM main_table 
WHERE id IN ( SELECT id FROM sub_table WHERE SOMECODITION)
AND
(select count(Distinct sid) 
from (select s.id sid,m.id mid from sub_table s left join main_table m on 
s.id = m.id where s.SOMECONDITION) )
= (select count(Distinct mid) 
from (select s.id sid,m.id mid from sub_table s left join main_table m on 
s.id = m.id where s.SOMECONDITION) )

This is rather painful in MySQL. The following gets the number of matches:

SELECT COUNT(DISTINCT id)
FROM main_table
WHERE id IN ( SELECT id FROM sub_table WHERE SOMECODITION);

If you only want to select the rows, I would suggest that you get the count in php and use conditional logic there. But, you can also do that in SQL:

SELECT mt.*
FROM main_table mt
WHERE mt.id IN ( SELECT st.id FROM sub_table st WHERE SOMECONDITION) AND
      (SELECT COUNT(DISTINCT mt.id)
       FROM main_table mt
       WHERE mt.id IN (SELECT st.id FROM sub_table st WHERE SOMECONDITION)
      ) =
      (SELECT COUNT(DISTINCT st.id) FROM sub_table st WHERE SOMECONDITION);

You need an inner join in this case.

SELECT m.* FROM main_table INNER JOIN sub_table s ON m.id = s.id WHERE SOMECODITION

I assume the SOMECODITION contains only conditions against sub_table . With SOMECODITION , it's guaranteed that the result from sub_table must meet the condition and with INNER JOIN , all id's from sub_table must be found in main_table in order to return something from main_table .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM