Emil: MySQL LEFT JOIN. Was geht da genau vor sich?

Hallo,

ich habe mir in der Mysql Doku die Beschreibung zu (LEFT) JOIN wirklich angesehen, allerdings hilft es mir nicht wirklich, weil es so schwer beschrieben ist.

Da steht z.B.: Der NATURAL [LEFT] JOIN zweier Tabellen ist definiert als semantisch identisch äquivalent zu einem INNER JOIN oder einem LEFT JOIN mit einer USING-Klausel, die alle Spalten nennt, die in beiden Tabellen existieren.

Das ist mir (noch) zu hoch. Ich bin nicht so ein Mysql Profi, dass ich das alles verstehe.

Ich habe jetzt zwar schon einige erfolgreiche Versuche mit den JOIN Befehlen hinter mir, allerdings habe ich immer noch keine rechte Vorstellung, was da in der Datenbank eigentlich vor sich geht.

Ich würde mich wikrlich freuen, wenn mir jemand in einfachen Worten erklären könnte, was die Mysql Datenbank bei den Befehlen JOIN, LEFT JOIN und RIGHT JOIN eigentlich macht.

Ich habe nämlich einmal eine Abfrage mit LEFT JOIN gemacht, die mit RIGHT JOIN genau das gleiche Ergebnis gebracht hat. Manchmal geht das aber nicht.

Das bringt mich alles etwas durcheinander.

Danke schon jetzt, euer Emil

  1. Hallo,

    ein Join ist eigentlich nichts mysql-spezifisches, sondern gehört zu sql. Joins dienen dazu Daten von verschiedenen tabellen auf verschiedene Art und Weise anzuzeigen. Bei einem Left-Join z.B. werden alle felder der linken tabelle genommen und mit der rechten verknüft. Dabei muss nichts in der rechten stehen. Ein Beispiel:

    SELECT p.persnr, pname, fmnr, vwgrad, vorname FROM persdat p LEFT JOIN fmitglieder f ON p.persnr = f.persnr

    => Persnr     Pname     Fmnr   Vwgrad       Vorname
       9          bind
       8          volt      1       1           Christa
       7          Merieris
       5          Luft

    Bei einem right-Joing geschieht genau das umgekehrte wie beim left join.  Der Outer-Join entspricht dem Equi- Join. Das ist einfach da wird nur über den Schlüssel verknüft. a la p.persnr = f.persnr

    MFG xss

    1. Hm, und wie ist das mit dem p.persnr? Muss man bei einer JOIN Abfrage immer "Tabellenname.Spaltenname" schreiben, oder reicht auch nur "Spaltenname"?

      1. Hm, und wie ist das mit dem p.persnr?

        p ist nur eine Abkürzung für die Tabelle

        Muss man bei einer JOIN Abfrage immer "Tabellenname.Spaltenname" schreiben, oder reicht auch nur "Spaltenname"?
        das weiss ich gerade gar nicht genau aber ich glaube es muss immer der fqn (fully qualified name) verwendet werden.

        MFGxss

        1. Mir ist gerade etwas aufgefallen. Ich wollte ein LEFT JOIN machen und alle Tabellen Zählen. Also habe ich COUNT(tabelle1.*) angegeben, aber das führt zu einer Fehlermeldung. Aber mit COUNT(*) funktioniert es.

          Wäre nett, wenn mich da jemand aufklären könnte.

          1. Mir ist gerade etwas aufgefallen. Ich wollte ein LEFT JOIN machen und alle Tabellen Zählen. Also habe ich COUNT(tabelle1.*) angegeben, aber das führt zu einer Fehlermeldung. Aber mit COUNT(*) funktioniert es.

            »»
            Also, das Problem ist das Count nur einen Wert zurückgibt und Der Join eine anderen Anzahl an Feldern zurückgibt. Du kannst den Count meines Wissens ins Joins nicht verwenden.

            Wäre nett, wenn mich da jemand aufklären könnte.

            MFg xss

            1. Doch kann ich. Wie gesagt gehts ja, wenn ich nur COUNT(*) benutze. Nur mit COUNT(tabelle1.*), was ja eigentlich auch gehen müsste, gehts nicht.

              Oder gibt es vielleicht eine andere Schreibweise um alle Datensätze einer Tabelle zu wählen? Also nicht Tabellenname.* ?

              1. ne,

                was anderes gibst nicht.

                MFg xss

                1. Naja, dann mach ichs eben ohne Tabellenname davor.

                  Kann man eigentlich auch mehr als 2 Tabellen mit einem JOIN Befehl verknüpfen?

                  1. Ja,

                    nur dann müssen die Schlüssel natürlich in jeder Tabelle sein.

                    mfg xss

                    1. Halihallo Excess2000

                      nur dann müssen die Schlüssel natürlich in jeder Tabelle sein.

                      Nein. Ein JOIN verknüpft Tabellen, wie sie verknüpft werden bestimmst alleine _du_.
                      Du brauchst keine Schlüssel um Tabellen zu verknüpfen (auch wenn es nicht sehr oft
                      vorkommen mag).

                      @Emil: Natürlich kannst du mehr als zwei Tabellen verknüpfen. Die Anzahl hängt
                      von der Datenbank ab (wieviele Tabellen) und wieviel Ressourcen auf dem Rechner frei sind
                      (das verknüpfen der Tabellen braucht Speicher und Rechnenleistung)...

                      Einige Lesetipps für dich, Emil:
                      http://www.mysql.com/doc/de/JOIN.html
                      http://www.mysql.com/doc/de/SELECT.html
                      http://www.mysql.com/doc/de/Group_by_functions.html

                      Viele Grüsse

                      Philipp

                      1. Du brauchst keine Schlüssel um Tabellen zu verknüpfen (auch wenn es nicht sehr oft
                        vorkommen mag).

                        Wie willst du denn einen Join ohne >Schlüssel durchführen?

                        MFG xss

                        1. Halihallo Excess2000

                          Du brauchst keine Schlüssel um Tabellen zu verknüpfen (auch wenn es nicht sehr oft
                          vorkommen mag).
                          Wie willst du denn einen Join ohne >Schlüssel durchführen?

                          Kunde

                          kundenname
                          ist_aktiv   : Mögliche Werte 0 oder 1

                          Fehler

                          ist_aktiv
                          Meldung     : Account nicht zugänglich oder OK, einloggen

                          SELECT Meldung FROM Kunde NATURAL JOIN Fehler

                          Das ist ein Join _ohne_ Schlüssel (auch wenn er höchst sinnfrei ist, wie ich bereits
                          auch gesagt habe).

                          Der Sinn von Primary Keys (und das meinst du wohl mit Schlüssel) ist die eindeutige
                          Kennzeichnung für einen bestimmten Datensatz. Der Sinn von Foreign Keys ist es, einen
                          Primary Key einer anderen Relation/Tabelle zu referenzieren (oder NULL). Beide haben
                          für JOIN keine "besondere" Bedeutung und verhalten sich so, wie jedes andere
                          Attribut/Spalte.

                          Folge: Schlüssel, sei nun Primary oder Foreign gemeint, sind für JOIN's keine notwendige
                          Voraussetzung.

                          Viele Grüsse

                          Philipp

                      2. Danke, die Doku habe ich ja schon gelesen, aber wie die geschrieben ist, da muss man schon Experte sein um das zu verstehen.

                        Verknüpfen braucht viel Rechenleistung?

                        Heißt das es ist eigentlich besser mehrere SELECTs zu machen, anstatt alles mit einem SELECT und ein paar Verknüpfungen?

                        1. Halihallo Emil

                          Danke, die Doku habe ich ja schon gelesen, aber wie die geschrieben ist, da muss man schon Experte sein um das zu verstehen.

                          Man muss sich am Anfang vielleicht einfach mehr Zeit nehmen, aber verständlich ist sie
                          alleweil; nur, dass man als "Anfänger" vielleicht sich erstmal wirklich mit der ganzen
                          Doku beschäftigen sollte und sich in die Grundlagen der Datenbank-"Wissenschaft"
                          einarbeiten muss.

                          Verknüpfen braucht viel Rechenleistung?
                          Heißt das es ist eigentlich besser mehrere SELECTs zu machen, anstatt alles mit einem SELECT und ein paar Verknüpfungen?

                          Der JOIN hat einen Sinn, nämlich zwei Tabellen über _selbstdefinierte_ Bedingungen zu
                          verknüpfen. Meistens sind die Bedingungen derart "komplex", dass man dies wirklich
                          lieber der Datenbank überlässt (JOIN), als diese irgendwie über zwei Queries zu lösen.
                          Zudem: Wenn du zwei Abfragen hast, musst du diese in der Programmlogik selber verbinden
                          und die 4GL (u.a. PHP, Perl, ASP etc.) sind da einfach viel, viel langsamer als die
                          Datenbank.
                          Um dir dennoch eine Antwort zu geben: Es macht in 99% aller Fälle _keinen_ Sinn, den
                          JOIN in einer Programmlogik "nachzubauen/simulieren", du solltest darum bemüht sein,
                          dies in einem Query zu lösen (sprich JOIN zu verwenden).

                          JOIN's brauchen Rechenleistung, das stimmt; diese Rechenleistung brauchst du jedoch
                          bei einer eigenständig programmierten Lösung auch, in den meisten Fällen noch viel,
                          viel mehr.

                          Viele Grüsse

                          Philipp

                          1. Danke für die Erklärung. Ich möchte eben so resourcensparend wie möglich programmieren.

                            Mit den einfachen JOINs komme ich jetzt schon recht gut zurecht.
                            Das einzige, was noch nicht funktioniert sind mehrere JOINs in einer Abfrage.

              2. Halihallo Emil

                Oder gibt es vielleicht eine andere Schreibweise um alle Datensätze einer Tabelle zu wählen? Also nicht Tabellenname.* ?

                SELECT COUNT(*) FROM Tabellenname

                oder s. letztes Posting (das mit JOIN).

                Viele Grüsse

                Philipp

          2. Halihallo Emil

            Mir ist gerade etwas aufgefallen. Ich wollte ein LEFT JOIN machen und alle Tabellen Zählen. Also habe ich COUNT(tabelle1.*) angegeben, aber das führt zu einer Fehlermeldung. Aber mit COUNT(*) funktioniert es.

            Nun, das Ergebnis einer SQL-Abfrage ist wieder eine ganz "normale" _einzelne_ Tabelle,
            eine Angabe der Tabelle macht also keinen Sinn. COUNT(*) gibt dir einfach die Anzahl
            Datensätze in dem SQL-Ergebnis zurück. Zudem sei angemerkt, dass COUNT(*) eine
            Aggregatsfunktion ist, demnach eigentlich mit GROUP BY zu verwenden ist[1].

            Ein Beispiel, was gleich auch deine Frage beantwortet:

            SELECT erste.id, COUNT(*)
            FROM erste_tabelle AS erste
                 LEFT OUTER JOIN zweite_tabelle AS zweite ON zweite.erste_id=erste.id
            GROUP BY erste.id

            so kannst du zu jeder erste.id die Anzahl Datensätze in der Tabelle zweite_tabelle
            ausgeben lassen, die über zweite.erste_id=erste.id verknüpft werden. Beispiel im
            Beispiel: Du hast Kunden, die Artikel bestellten => Wieviele Artikel pro Kunde?

            [1] Natürlich geht's auch ohne GROUP BY...

            Viele Grüsse

            Philipp

        2. Halihallo Excess2000

          Hm, und wie ist das mit dem p.persnr?
          p ist nur eine Abkürzung für die Tabelle

          Muss man bei einer JOIN Abfrage immer "Tabellenname.Spaltenname" schreiben, oder reicht auch nur "Spaltenname"?
          das weiss ich gerade gar nicht genau aber ich glaube es muss immer der fqn (fully qualified name) verwendet werden.

          Nun, sinnvoll ist es, es geht jedoch bedingt auch ohne. Bedingt heisst: Der Name darf
          in keiner anderen Tabelle/Relation vorkommen, sonst bricht MySQL mit "Column: '...' in
          field list is ambiguous" ab. Es ist jedoch möglich Spalten, deren Name eindeutig ist
          bezogen auf die verwendeten Tabellen (FROM-Klausel), nur mit Namen (ohne Tabelle oder
          Alias) anzusprechen.

          Viele Grüsse

          Philipp