Pregunta

Dada una tabla de elementos, una tabla de etiquetas y una tabla de unión entre ellas, ¿cuál es una manera buena y eficiente de implementar consultas de la forma:

p1 Y p2 Y ... Y pn Y NO n1 Y NO n2 ... Y NO nk

Estoy usando SQL. Entonces, para encontrar todos los elementos que coincidan con todas las etiquetas p1 ... pn y ninguno de n1 ... nk?

¿Hay un buen " estándar " ¿Solución para esto?

¿Fue útil?

Solución

Es difícil decirlo sin saber tu esquema, pero algo como esto funcionaría:

select article_id from articles
inner join tag t1 on t1.article_id=articles.article_id and t1.tag='included_tag'
inner join tag t2 on t2.article_id=articles.article_id and t2.tag='another_included_tag'
left outer join tag t3 on t3.article_id=articles.article_id and t3.tag='dont_include_tag'
left outer join tag t4 on t4.article_id=articles.article_id and t4.tag='also_dont_include_tag'
where t3.tag_id is null and t4.tag_id is null

unión interna a las etiquetas que se incluirán, y realice una combinación conjunta (unión externa + donde la columna requerida es nula) a las etiquetas que no se incluirán

Otros consejos

Creo que esto es lo que estás buscando:

SELECT * FROM TABLE_NAME WHERE COLUMN1 IN ('value1','value2','value3') AND COLUMN1 NOT IN ('value4','value5','value6')

Si no, házmelo saber. Es posible que haya malinterpretado tu pregunta.

Depende de cómo almacene las etiquetas en la base de datos, pero probablemente desee el operador IN :

SELECT tag FROM myTags WHERE tag IN ('p1','p2',...)
SELECT tag FROM myTags WHERE tag NOT IN ('p1','p2',...)
SELECT DISTINCT itemID FROM ItemsTags it, Tags t 
WHERE it.tagID = t.ID AND t.tag IN ('p1','p2','p3') AND t.tag NOT IN ('p4','p5','p6')
SELECT i.title
  FROM items i
 WHERE EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag1')
   AND NOT EXISTS(SELECT * FROM join_table j JOIN tags t ON t.id = j.tag_id WHERE j.item_id = i.id AND t.name = 'tag2')

El servidor SQL hace un buen trabajo con esta construcción, pero Oracle podría necesitar algunas sugerencias para hacerlo bien (al menos lo hizo hace 5 años).

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