简体   繁体   中英

Select records where every record in one-to-many join matches a condition

How can I write a SQL query that returns records from table A only if every associated record from table B matches a condition?

I'm working in Ruby, and I can encode this logic for a simple collection like so:

array_of_A.select { |a| a.associated_bs.all? { |b| b.matches_condition? } }

I am being generic in the construction, because I'm working on a general tool that will be used across a number of distinct situations.

What I know to be the case is that INNER JOIN is the equivalent of

array_of_A.select { |a| a.associated_bs.any? { |b| b.matches_condition? } }

I have tried both:

SELECT DISTINCT "A".* FROM "A"
INNER JOIN "B"
  ON "B"."a_id" = "A"."id"
WHERE "B"."string' = 'STRING'

as well as:

SELECT DISTINCT "A".* FROM "A"
INNER JOIN "B"
  ON "B"."a_id" = "A"."id"
  AND "B"."string' = 'STRING'

In both cases (as I expected), it returned records from table A if any associated record from B matched the condition. I'm sure there's a relatively simple solution, but my understanding of SQL just isn't providing it to me at the moment. And all of my searching thru SO and Google has proven fruitless.

I would suggest the following:

select distinct a.* 
from a inner join 
(
    select b.a_id 
    from b 
    group by b.a_id 
    having min(b.string) = max(b.string) and min(b.string) = 'string'
) c on a.id = c.a_id

Alternatively:

select distinct a.* 
from a inner join b on a.id = b.a_id
where not exists (select 1 from b c where c.a_id = a.id and c.string <> 'string')

Note: In the above examples, only change the symbols a and b to the names of your tables; the other identifiers are merely aliases and should not be changed.

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