Estou procurando uma maneira de criar uma consulta para fazer o seguinte:
Vamos considerar 3 tabelas:
- produtos: Lista de produtos
- tags: lista de tags
- tag_ties: tabela usada para associar uma tag a um produto
Vamos considerar esta estrutura para cada tabela:
Produtos:
- id (int, incremento automático)
- nome (varchar, nome do produto)
Tag:
- ID (incremento automático)
- label (varchar, label da tag)
Tag_ties:
- id (int, incremento automático)
- tag_id (int, referência a um ID de tag)
- ref_id (int, referência a um ID do produto)
O que eu quero:
Obtenha todos os produtos marcados com as tags 10, 11 e 12, por exemplo.
Esta consulta não funciona, pois retorna os produtos com pelo menos uma das tags:
select
p.name as name,
p.id as id
from
products p inner join tag_ties ties
on
p.id=ties.ref_id
where
ties.ref_id=p.id and
ties.tag_id in (10,11,12)
group by
p.id
order by
p.name asc
Você pode resolver esse problema usando instruções de interseção. Faça uma seleção separada para cada tag_id e junte-se a elas com interseções e você obterá apenas os registros que correspondem às três tag_ids.
Aqui está um artigo de referência sobre o uso de interseção
Você também pode usar uma exibição temporária para tornar isso um pouco melhor.
fonte
A subconsulta da resposta selecionada não é necessária. Para selecionar produtos com todos os IDs de tag fornecidos, a consulta pode ser simplesmente:
Estendendo essa idéia, também podemos consultar com base nos rótulos das tags em uma única captura. Para selecionar produtos com as tags
('foo', 'bar', 'baz')
:Para complicar um pouco, podemos usar uma subconsulta para misturar intersecção (
AND
) e união (OR
). A consulta abaixo retornará produtos com todas as tags do grupo('foo', 'bar')
e pelo menos uma das tags do grupo('baz', 'ding')
:fonte
JOIN
? Não, tecnicamente você não, mas há alguma razão para não usá-lo? E voltando à notação SQL-89 de junções implícitas?