Você usaria agregações condicionais aqui. Para Vermelho e Azul, por exemplo, você deseja encontrar cartões onde
- ambas as cores existem
- não existe outra cor
Isso significa que se eu contar Vermelho e Azul para uma carta, devo obter 2. Se contar todas as cores, também devo obter 2. (O mesmo para uma, três ou mais cores.)
Portanto, use esta consulta e altere apenas as cores mencionadas e o número de cores:
select *
from cards_data where id in
(
select cards_id
from con_cards_colors
group by cards_id
having count(case when colors_id in (select id from colors where name in ('Red','Blue')) then 1 end) = 2 -- i.e. find all
and count(*) = 2 -- i.e. find only those and no others
);