MySQL-Grenze mit viele zu viele Beziehung
Frage
ein SCHEMA für die Implementierung Tags Gegeben
ITEM ItemId, ItemContent
TAG TagId, TagName
ITEM_TAG ItemId, TagId
Was ist der beste Weg, um die Anzahl der Elemente zurück zu begrenzen, wenn mit den Umbauten der Auswahl?
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
ist natürlich der einfachste Weg, sie alle wieder zu bekommen, aber mit einem Limit-Klausel zusammenbricht, weil Sie ein Duplikat aller Elemente für jeden Tag erhalten, die in Richtung der Anzahl der Zeilen in LIMIT zählt.
Lösung
Meine zweite Lösung verwendet eine MySQL-Funktion GROUP_CONCAT () Alle Tags zu kombinieren, um das Element in eine kommagetrennte Zeichenfolge in der Ergebnismenge entsprechen.
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;
Die GROUP_CONCAT () Funktion ist eine MySQL-Funktion, es ist nicht Teil des Standard-SQL.
Andere Tipps
Vielleicht so etwas wie
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
Mein erster Vorschlag ist eine Unterabfrage zu verwenden, um die Liste der Artikel-IDs zu generieren und Artikel zurückgeben, diese Artikel-IDs entsprechen. Aber dies schließt nicht die TagName in der Ergebnismenge. Ich werde eine separate Antwort mit einer anderen Lösung vor.
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')
);
Dies ist eine nicht-korrelierten Unterabfrage, so dass ein guter SQL-Engine es aus Faktor sollte und es nur einmal ausgeführt werden.
Sie können auch Distinct / Gruppierung verwenden
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