MySQL与多对多关系的限制
时间:2020-03-06 15:04:37 来源:igfitidea点击:
给出了用于实施标签的SCHEMA
物品
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中的行数。
解决方案
也许像
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
我的第一个建议是使用子查询来生成商品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引擎应将其分解出来并仅运行一次。
我的第二个解决方案使用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的一部分。
我们还可以使用"不同/分组依据":
`
SELECT DISTINCT TagID,TagName FROM((TAG T
INNER JOIN ITEM_TAG I_T ON T.TagID = I_T.TagID)
内联项目I ON I_T.ItemID = I.ItemID)
TagID,TagName的分组