Как я могу реализовать поиск по булевому тегу в SQL? - PullRequest
3 голосов
/ 02 марта 2009

Учитывая таблицу элементов, таблицу тегов и таблицу соединения между ними, что является хорошим и эффективным способом реализации запросов в форме:

p1 AND p2 AND ... AND pn AND NOT n1 AND NOT n2 ... AND NOT nk

Я использую SQL. Итак, чтобы найти все элементы, которые соответствуют всем тегам p1 ... pn и ни одному из n1 ... nk?

Есть ли хорошее "стандартное" решение для этого?

Ответы [ 5 ]

2 голосов
/ 02 марта 2009

Трудно сказать, не зная вашей схемы, но что-то вроде этого будет работать:

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

внутреннее соединение с тегами, которые должны быть включены, и анти-объединение (внешнее соединение +, где обязательный столбец равен нулю) с тегами, которые не должны быть включены

2 голосов
/ 02 марта 2009

Это зависит от того, как вы храните теги в базе данных, но вам, вероятно, нужен оператор IN:

SELECT tag FROM myTags WHERE tag IN ('p1','p2',...)
SELECT tag FROM myTags WHERE tag NOT IN ('p1','p2',...)
2 голосов
/ 02 марта 2009

Я думаю, это то, что вы ищете:

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

Если нет, дайте мне знать. Возможно, я неправильно понял ваш вопрос.

1 голос
/ 02 марта 2009
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')
0 голосов
/ 02 марта 2009
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')

SQL-сервер хорошо справляется с этой конструкцией, но Oracle, возможно, понадобится несколько подсказок, чтобы сделать это правильно (по крайней мере, 5 лет назад).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...