Получение записей, имеющих теги T1 и T2.
Вопрос
Мне нужен запрос sql, который будет извлекать все элементы, имеющие оба тега, а не какой-либо из тегов.У меня уже есть запрос, но он возвращает все элементы, содержащие оба тега, а не ожидаемый результат.Подробное описание найдете ниже.Спасибо!
Структура таблицы:
ITEMS TABLE
------------
item_id
item_name
TAGS TABLE
----------
tag_id
tag_name
ITEMTAGS TABLE
---------------
tag_id
item_id
Запрос:
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
Результат:Все предметы, имеющие Т1 или Т2.
Ожидаемый результат:Все предметы, у которых есть как T1, так и T2.
Решение
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;
Другие советы
Если ваша база данных поддерживает ключевое слово intersect (SqlServer поддерживает), вы можете написать:
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
)
Если нет, вам нужно будет сделать что-то вроде:
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
)
При втором запросе позаботьтесь о возможных проблемах с производительностью из-за ItemTags1.item_id = ItemTags2.item_id .Для хорошей работы вам понадобится индекс внешнего ключа.