2

タグを実装するためのスキーマが与えられた

ITEM ItemId、ItemContent

TAG 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

4 に答える 4

5

私の 2 番目のソリューションは、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 の一部ではありません。

于 2008-10-03T16:03:57.587 に答える
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
于 2008-10-03T14:31:49.957 に答える
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 エンジンはこれを除外して 1 回だけ実行する必要があります。

于 2008-10-03T15:59:59.857 に答える
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

于 2008-10-03T16:13:11.717 に答える