给出用于实施标签的SCHEMA
ITEM ItemId,ItemContent
标签 TagId,TagName
ITEM_TAG ItemId,TagId
使用标签选择时,限制返回的ITEMS数量的最佳方法是什么?
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中的行数。
答案 0 :(得分:5)
我的第二个解决方案使用MySQL函数GROUP_CONCAT()将匹配项目的所有标记组合成结果集中逗号分隔的字符串。
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;
GROUP_CONCAT()函数是一个MySQL特性,它不是标准SQL的一部分。
答案 1 :(得分:1)
也许像
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
答案 2 :(得分:0)
我的第一个建议是使用子查询生成商品ID列表,并返回与商品ID匹配的商品。但是这不包括结果集中的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引擎应该将其分解出来并只运行一次。
答案 3 :(得分:0)
你也可以使用Distinct / Group By:
SELECT DISTINCT TagID, TagName FROM ((TAG T
INNER JOIN ITEM_TAG I_T ON T.TagID = I_T.TagID)
INNER JOIN ITEM I ON I_T.ItemID = I.ItemID)
GROUP BY TagID, TagName