多対多の関係を持つMySQLの制限
質問
タグを実装するためのスキーマを指定
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の行数にカウントされます。
解決
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の一部ではありません。
他のヒント
おそらく次のようなもの
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エンジンはこれをファクタリングして一度だけ実行する必要があります。
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
所属していません StackOverflow