Abfrage von m:n Beziehung



  • Hi,

    folgende Tabellen:

    Blogentry: id, name, title, etc.
    Tags: id, name
    Entrytags: entryid, tagid

    Entries 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 tags

    SELECT 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


Anmelden zum Antworten