Ограничение MySQL с отношением многие ко многим
Дана схема реализации тегов
Пункт ItemId, ItemContent
Тег TagId, TagName
ITEM_TAG ItemId, TagId
Как лучше всего ограничить количество возвращаемых элементов при выборе с помощью тегов?
SELECT i.ItemContent, t.TagName FROM item i
INNER JOIN ItemTag it ON i.id = it.ItemId
INNER JOIN tag t ON t.id = it.TagId
, Конечно, самый простой способ получить их все обратно, но использование предложения limit ломается, потому что вы получаете дубликат всех элементов для каждого тега, который засчитывается в число строк в LIMIT.
4 ответа:
Мое второе решение использует функцию MySQL GROUP_CONCAT () для объединения всех тегов, соответствующих элементу, в строку, разделенную запятыми в результирующем наборе.
Функция GROUP_CONCAT () является функцией MySQL,она не является частью стандартного SQL.SELECT i.ItemContent, GROUP_CONCAT(t.TagName ORDER BY t.TagName) AS TagList FROM item AS i INNER JOIN ItemTag AS it ON i.id = it.ItemId INNER JOIN tag AS t ON t.id = it.TagId GROUP BY i.ItemId;
Может быть, что-то вроде
select i.ItemContent, t.TagName from (SELECT ItemId, ItemContent FROM item limit 10) i INNER JOIN ItemTag it ON i.ItemId = it.ItemId --You will miss tagless items here! INNER JOIN tag t ON t.id = it.TagId
Мое первое предложение - использовать подзапрос для создания списка идентификаторов элементов и возврата элементов, соответствующих этим идентификаторам элементов.но это не включает TagName в ваш результирующий набор. Я представлю отдельный ответ с другим решением.
SELECT i.ItemContent FROM item AS i WHERE i.id IN ( SELECT it.ItemId FROM ItemTag AS it INNER JOIN tag AS t ON (t.id = it.TagId) WHERE t.TagName IN ('mysql', 'database', 'tags', 'tagging') );
Это некоррелированный подзапрос, поэтому хороший SQL-движок должен учитывать его и запускать только один раз.