简体   繁体   English

仅当所有相关记录匹配时才选择记录

[英]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.我想从 table1 中选择所有相关 table2 记录满足条件的所有记录。 Only when the ALL table 2 records satisfy it.只有当 ALL 表 2 记录满足它时。

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 :如果您想要m中所有状态为3的行I ,则使用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 .请注意,这会匹配table2中没有匹配项的行。 That technically meets the requirement that all rows have a status of 3 .这在技术上满足所有行的状态为3 But if you want to require a row, you can add an exists condition:但是如果你想要求一行,你可以添加一个exists条件:

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) .这两者都可以利用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 ).使用某种形式的聚合的方法需要额外的工作,并且在大型数据集上的性能应该会table2一些(特别是当table2有很多匹配项时)。

You could drop the join to table2 and change the all to in or exists.您可以删除与 table2 的连接并将全部更改为 in 或exists。 or you could add t.status = 3 to the on clause and get rid of the where clause.或者您可以将 t.status = 3 添加到 on 子句并摆脱 where 子句。

You can add NOT EXISTS to the ON clause:您可以将NOT EXISTS添加到ON子句:

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 .这样您就可以从table1选择与table2相关的所有行,并且相关行都满足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 :或者,在没有join ,在WHERE子句中使用返回满足条件Status = 3table2所有Id的子查询:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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