I have two tables:
foos:
id | f_name |
---|---|
1 | xxx |
2 | yyy |
3 | zzz |
foo_bars:
id | foo_id | active |
---|---|---|
1 | 1 | false |
2 | 1 | false |
3 | 1 | false |
4 | 2 | true |
5 | 2 | false |
6 | 2 | true |
7 | 3 | false |
7 | 3 | true |
Each foo
should have each an active foo_bar
, and only one. Because of a poorly designed process, it sometimes happened that either more than one foo_bar
was set to active=true
, or that no foo_bar
was set to active. Neither is a valid scenario.
I need to find those rows on foos
where the linked foo_bars
rows with active are != 1.
E.g. in the above scenario I'd like to get:
1,xxx
2,yyy
Can I accomplish this with a single query?
CodePudding user response:
I think this would be a good use of the HAVING
clause in a GROUP BY
query:
select
f.id, f.f_name
from foos f
left join foo_bars b on f.id = b.foo_id
group by
f.id, f.f_name
having
count (*) filter (where b.active) != 1
CodePudding user response:
You should be able to do this with an outer join and simple aggregation:
select
*
from
(
select
foo.id,
coalesce(count (foo_bar.id),0) as id_count
from
foo
left join foo_bar
on foo.id = foo_bar.foo_id
group by
foo.id
) t
where id_count <> 1