it-swarm.com.de

Linke Verknüpfung oder Auswahl aus mehreren Tabellen mit Komma (,)

Ich bin neugierig, warum wir LEFT JOIN verwenden müssen, da wir mit Kommas mehrere Tabellen auswählen können.

Was sind die Unterschiede zwischen LEFT JOIN und der Verwendung von Kommas zum Auswählen mehrerer Tabellen?.

Welches ist schneller?

Hier ist mein Code:

   SELECT mw.*, 
          nvs.* 
     FROM mst_words mw 
LEFT JOIN (SELECT no as nonvs, 
                  owner, 
                  owner_no, 
                  vocab_no, 
                  correct 
             FROM vocab_stats 
            WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0 ) 
      AND mw.level = 1

...und:

SELECT * 
  FROM vocab_stats vs, 
       mst_words mw 
 WHERE mw.no = vs.vocab_no 
   AND vs.correct > 0 
   AND mw.level = 1 
   AND vs.owner = 1111
14
bbnn

Um völlig gleichwertig zu sein, sollte zunächst die erste Abfrage geschrieben worden sein

   SELECT mw.*, 
          nvs.* 
     FROM mst_words mw 
LEFT JOIN (SELECT *
             FROM vocab_stats 
            WHERE owner = 1111) AS nvs ON mw.no = nvs.vocab_no 
    WHERE (nvs.correct > 0 ) 
      AND mw.level = 1

So erzeugen mw. * Und nvs. * Zusammen den gleichen Satz wie der Singular der 2. Abfrage. Die Abfrage, die Sie geschrieben haben, kann einen INNER JOIN verwenden, da sie einen Filter für nvs.correct enthält.

Die allgemeine form

TABLEA LEFT JOIN TABLEB ON <CONDITION>

attemptsum TableB-Datensätze basierend auf der Bedingung zu finden. Wenn dies fehlschlägt, werden die Ergebnisse von TABLEA beibehalten, wobei alle Spalten von TableB auf NULL gesetzt werden. Im Gegensatz

TABLEA INNER JOIN TABLEB ON <CONDITION>

alsoattempts, um TableB-Datensätze basierend auf der Bedingung zu finden. Wenn jedoch fehlschlägt, wird der betreffende Datensatz aus TableA aus dem Ausgabeergebnissatz entfernt.

Der ANSI-Standard für CROSS JOIN erzeugt ein kartesisches Produkt zwischen den beiden Tabellen.

TABLEA CROSS JOIN TABLEB
  -- # or in older syntax, simply using commas
TABLEA, TABLEB

Die Absicht der Syntax ist, dass JEDE Zeile in TABLEA mit JEDER Zeile in TABLEB verbunden wird. So erzeugen 4 Zeilen in A und 3 Zeilen in B 12 Zeilen. In Kombination mit Bedingungen in der WHERE-Klausel führt dies manchmal zu demselben Verhalten wie INNER JOIN, da sie dasselbe ausdrücken (Bedingung zwischen A und B => keep or not). Es ist jedoch beim Lesen viel klarer, was die Absicht ist, wenn Sie INNER JOIN anstelle von Kommas verwenden.

In Bezug auf die Leistung verarbeiten die meisten DBMS eine LEFT-Verknüpfung schneller als eine INNER JOIN. Die Komma-Notation kann dazu führen, dass Datenbanksysteme die Absicht falsch interpretieren und einen fehlerhaften Abfrageplan erzeugen - ein weiterer Pluspunkt für die SQL92-Notation.

Warum brauchen wir LEFT JOIN? Wenn die Erklärung von LEFT JOIN oben immer noch nicht ausreicht (halten Sie Datensätze in A ohne Übereinstimmungen in B), sollten Sie dies berücksichtigen, wenn Sie eine komplexe UNION zwischen zwei Sätzen benötigen, die die alte Komma-Notation verwendet der gleiche Effekt. Aber wie bereits gesagt gilt dies nicht für Ihr Beispiel, bei dem es sich wirklich um einen INNER JOIN JOIN handelt, der sich hinter einem LEFT JOIN versteckt.

Anmerkungen:

  • Der RECHTE JOIN ist derselbe wie LEFT, außer dass er mit TABLEB (rechte Seite) anstelle von A beginnt.
  • RECHTE und LINKE VERBINDUNGEN sind AUSSEN-VERBINDUNGEN. Das Word-OUTER ist optional, d. H. Es kann als LEFT OUTER JOIN geschrieben werden.
  • Der dritte Typ des OUTER-Joins ist der FULL OUTER-Join, aber das wird hier nicht besprochen.
4
RichardTheKiwi

Das Trennen des JOIN vom WHERE erleichtert das Lesen, da die Join-Logik nicht mit den WHERE-Bedingungen verwechselt werden kann. Es ist im Allgemeinen auch schneller, da der Server nicht zwei separate Abfragen durchführen und die Ergebnisse kombinieren muss.

Die beiden Beispiele, die Sie gegeben haben, sind nicht wirklich gleichwertig, da Sie im ersten Beispiel eine Unterabfrage eingefügt haben. Dies ist ein besseres Beispiel:

SELECT vs.*, mw.*
FROM vocab_stats vs, mst_words mw
LEFT JOIN vocab_stats vs ON mw.no = vs.vocab_no
WHERE vs.correct > 0 
AND mw.level = 1
AND vs.owner = 1111
0
Bazmatiq