Another way using Postgres aggregate functions that I thought would work but actually doesn't!
(don't try this):
where bool_or(a, b, c, d) and not bool_and(a, b, c, d)
This will work but is much more verbose than the other answers:
where exists
(select 1
from (values (a), (b), (c), (d)) as b(i)
having bool_or(i) and not bool_and(i)
)
(somewhat simplified):
where (select bool_or(i) and not bool_and(i)
from (values (a), (b), (c), (d)) as b(i)
)
This however, works. It's based on FALSE < TRUE
ordering:
where greatest(a,b,c,d) = true and least(a,b,c,d) = false
or:
where greatest(a,b,c,d) and not least(a,b,c,d)
or just:
where greatest(a,b,c,d) > least(a,b,c,d)
true
orfalse
. The answer (query and result) are the same ;)