Estoy tratando de consultar objetos que coinciden con TODO un conjunto determinado de etiquetas.¿Mysql join consulta para múltiples "etiquetas" (relación muchos-a-muchos) que coinciden con TODAS las etiquetas?
Básicamente, quiero que los usuarios puedan agregar más y más etiquetas para filtrar o "reducir" sus resultados de búsqueda, algo así como lo hace newegg.com.
Mi estructura de tabla es una tabla de Objetos, una tabla de Etiquetas, y una tabla de relaciones MANY: MANY ObjectsTags. Así que tengo una consulta de unión de este modo:
SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)
He intentado utilizar una cláusula IN/condición, así:
SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)
WHERE Tags.name IN ('tag1','tag2')
GROUP BY Objects.id
Pero aprendí que esta simula una serie de quirófanos, por lo que los más etiquetas usted agrega a la consulta los MÁS resultados que obtiene, en lugar de que el conjunto de resultados se reduzca como esperaba.
También he intentado hacer múltiples como dónde condiciones, asocian con un AND:
SELECT * FROM Objects
LEFT OUTER JOIN ObjectsTags ON (Objects.id=ObjectsTags.object_id)
LEFT OUTER JOIN Tags ON (Tags.id=ObjectsTags.tag_id)
WHERE Tags.name LIKE 'tag1'
AND Tags.name LIKE 'tag2'
GROUP BY Objects.id
Pero esto no devolvió resultados, ya que cuando los resultados se agrupan el EXTERIOR unió a la columna Tags.name solo contiene 'tag1', y no también 'tag2'. La fila de resultados donde 'tag2' coincide es "oculta" por GROUPing.
¿Cómo puedo asociar TODAS las etiquetas para obtener el efecto "angosto" o "desglosar" que estoy buscando? Gracias.
DISTINCT es necesario si no tiene una clave principal o restricción/índice exclusivo en el par de columnas en OBJECTTAGS para asegurarse de que no haya duplicados (estos serían falsos positivos). –
funciona muy bien! ¡Gracias! nunca pensé en usar HAVING de esa manera con los recuentos de filas. Para su información: estoy construyendo mi consulta en PHP para que la cláusula HAVING coincida con el número de etiquetas que estoy buscando, así que si fue ('tag1', 'tag2', 'tag3') Estoy buscando HAVING COUNT (DISTINCT t.name) = 3, para asegurarse de que el resultado tenga TODAS las etiquetas. – thaddeusmt
Awesome answer. Gracias ! –