简体   繁体   中英

select the records only if ALL related records match

Again I am stuck with a query. I want to select all records from table1 in which ALL related table2 records satisfy a condition. Only when the ALL table 2 records satisfy it.

I tried this. But it's not working.

select m.* from table1 m
 inner join table2 I on m.Id = I.Id
where 
I.Id = ALL (select t.Id from table2 t where t.Id = I.Id and t.Status = 3)

If you want the rows from m where all statuses are 3 in I , then use not exists :

select m.* 
from table1 m
where not exists (select 1
                  from table2 I 
                  where I.Id = m.Id and I.status <> 3
                 );

EDIT:

Note that this matches rows where there are no matches in table2 . That technically meets the requirement that all rows have a status of 3 . But if you want to require a row, you can add an exists condition:

select m.* 
from table1 m
where not exists (select 1
                  from table2 I 
                  where I.Id = m.Id and I.status <> 3
                 ) and
      exists (select 1
              from table2 I 
              where I.Id = m.Id and I.status = 3
             );

Both of these can take advantage of an index on table2(Id, status) . Methods that use some form of aggregation require additional work and should be a little less performant on large data sets (particularly when there are many matches in table2 ).

You could drop the join to table2 and change the all to in or exists. or you could add t.status = 3 to the on clause and get rid of the where clause.

You can add NOT EXISTS to the ON clause:

select m.* 
from table1 m inner join table2 I 
on m.Id = I.Id 
and not exists (select t.Id from table2 t where t.Id = m.Id and t.Status <> 3)

This way you select from table1 all the rows that are related to table2 and the related rows all satisfy the condition that Status = 3 .
Or, without a join , use in the WHERE clause a subquery that returns all the Id s of table2 that satisfy the condition Status = 3 :

select * 
from table1  
where Id in (
  select Id from table2
  group by Id
  having min(Status) = 3 and max(Status) = 3
)

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