Abfrage von m:n Beziehung
-
Hi,
folgende Tabellen:
Blogentry: id, name, title, etc.
Tags: id, name
Entrytags: entryid, tagidEntries und die Tags gehen eine m:n Beziehung ein, die durch "Entrytags" abgebildet wird.
Wie kann ich nun die Namen von Tags eines Entries bekommen?
Danke für Eure Hilfe!
-
Achso, ich suche das passende SQL statement.
-
Schön der Reihe nach:
- Was willst du haben: tags.name
- Einschränkungen oder Gruppierungen: ja, blogentry.id ist gegeben
- Wo finden sich die Spalten: blogentry und tagsSELECT tags.name -- das ist gesucht FROM tags, blogentry, entrytags -- aus diesen Tabellen WHERE tags.id = entrytags.tagid -- wegen der Substitution benötigt AND blogentry.id = entrytags.entryid -- wegen der Substitution benötigt AND blogentry.id = ??? -- das ist der gegebene Wert
Wenn du keine joins magst, gehts auch über subselects:
SELECT name FROM tags WHERE id IN ( SELECT tagid FROM entrytags WHERE entryid = ??? )
-
Danke zwutz, das erste Statement ist es. Das zweite verstehe ich nicht ganz.
Was meinst du mit "keine Joins". Ich sehe kein Join. Oder meinst du die verkettete "AND" query?
Geht es mit ner JOIN Anweisung eleganter?
-
Naja, wenn Du die Joins explizit anschreibst, sieht es eben ungefähr so aus:
SELECT tags.name FROM (tags INNER JOIN entrytags ON tags.id = entrytags.id) INNER JOIN blogentry ON blogentry.id = entrytags.entryid WHERE blogentry.id = 42;
Ist natürlich fein, gleich zu sehen, was wie zusammengejoint wird.
Da sieht man auch schön, dass Du wohl einfach das hier machen könntest:
SELECT tags.name FROM tags INNER JOIN entrytags ON tags.id = entrytags.id WHERE entrytags.entryid = 42;
-
nman, Deine zweite query sieht sehr gut aus. Das werde ich mal versuchen.
Danke
-
einen INNER JOIN kann man über zwei Wege bekommen.
Einer ist, explizit INNER JOIN zu schreiben (wie bei nmans Beispiel)
die andere, von mir oft bevorzugte Variante ist, das über WHERE zu machen (wie mein Beispiel)Also ist
FROM tabelleA INNER JOIN tabelleB ON tabelleA.ID = tabelleB.AID
vom Ergebnis das gleiche wie
FROM tabelleA, tabelleB WHERE tabelleA.ID = tabelleB.AID
mein zweites Beispiel war eine Möglichkeit für die, die keine JOINS verwenden können oder wollen (solls ja geben)
Der innere Query liefert eine Liste aller tag-ids, die zur angegebenen entry-id passen. Der äußere Query sucht dann zu jeder dieser IDs den passenden Namen
-
@Twutz
Das was du machst mag zwar das gleiche Ergebnis leben doch ist das nicht mit einem Inner Join zu vergleichen.
Zuerst wird from ausgeführt, dann where. Und bei einem impliziten Crossjoin werden halt unverhältnismäßig viel mehr Datensätze heranzgezogen die du dann nachträglich mit dem where erschlägst.
In diesem Zusammenhang verursacht das Crossjoin (wie du es verwendest) mehr arbeite als das Inner join