Pregunta

Necesito una consulta de SQL que recupere todos los elementos que tienen ambas etiquetas, no ninguna de las etiquetas. Ya tengo una consulta pero devuelve todos los elementos que tienen ambas etiquetas, resultado no esperado. Encuentra la descripción detallada a continuación. Gracias!

Estructura de la tabla:

ITEMS TABLE
------------
item_id
item_name

TAGS TABLE
----------
tag_id
tag_name

ITEMTAGS TABLE
---------------
tag_id
item_id

Consulta:

SELECT Items.* FROM Items 
INNER JOIN ItemTags ON Items.item_id = ItemTags.item_id
WHERE ItemTags.tag_id IN (T1, T2)
GROUP BY Items.item_id

Resultado: Todos los artículos que tienen T1 o T2

Resultado esperado: Todos los elementos que tienen T1 y T2

¿Fue útil?

Solución

select i.*
from items i, itemtags it1, itemtags it2
where i.item_id=it1.item_id and it1.tag_id=T1
and i.item_id=it2.item_id and it2.tag_id=T2;

Otros consejos

Si su base de datos admite la palabra clave de intersección (SqlServer) puede escribir:

SELECT Items.* 
FROM Items 
WHERE Items.item_id in 
/* intersection between items that have the tag T1 
   and the ones that have the tag T2 */ 
(
    SELECT item_id FROM ItemTags WHERE tag_id = T1
    INTERSECT 
    SELECT item_id FROM ItemTags WHERE tag_id = T2
)

Si no es así, deberás hacer algo como:

SELECT Items.* 
FROM Items 
WHERE Items.item_id in 
(
    SELECT ItemTags1.item_id 
    FROM ItemTags as ItemTags1 
        INNER JOIN ItemTags as ItemTags2 
        ON ItemTags1.item_id = ItemTags2.item_id 
    WHERE 
            ItemTags1.tag_id = T1
        AND ItemTags2.tag_id = T2
)

En la segunda consulta, resuelva los posibles problemas de rendimiento debido a ItemTags1.item_id = ItemTags2.item_id. Necesitará un índice en la clave externa para que funcione bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top