MySQL与多对多关系的限制

时间:2008-10-03 14:12:38

标签: mysql database tags tagging

给出用于实施标签的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中的行数。

4 个答案:

答案 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