Was ist der Grund für die Verwendung von Double Inner Join in dieser SQL-Anweisung?

10

Ich betrachte diese alte SQL-Abfrage. Das Bit, das ich nicht bekommen kann, ist, warum es innerlich dieselbe Tabelle zweimal in denselben Spalten verbindet. Ich spreche von Tabelle1 und Tabelle1, die mit dem Alias ​​"Table1Alias" verbunden sind.

SELECT DISTINCT othercolumns,
                Table1Alias.columna
FROM   maintable
       INNER JOIN secondarytable
               ON maintable.id1 = secondarytable.a_id1
       INNER JOIN table1
               ON secondarytable.id2 = table1.id3
       INNER JOIN table1 Table1Alias
               ON secondarytable.id2 = Table1Alias.id3
       INNER JOIN thirdtable
               ON table1.id4 = thirdtable.id5
       INNER JOIN fourthtable
               ON thirdtable.id6 = fourthtable.id7
       INNER JOIN fivetable
               ON thirdtable.id8 = fivetable.id9
       INNER JOIN sixthtable
               ON Table1Alias.columna = sixthtable.id10
       LEFT JOIN seventhtable
              ON thirdtable.id11 = seventhtable.id12
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09'
       AND secondarytable.type456 = 'cate'
       AND table1.type = '0'
       AND Table1Alias.columna = 'conn'
Mathematik
quelle

Antworten:

27

Es kann hilfreich sein, die Abfrage wie folgt umzuschreiben, sodass es offensichtlich ist, dass die beiden Verknüpfungen unterschiedlich sind , dh die Verknüpfungen zu unterschiedlichen Teilmengen (derselben Tabelle):

FROM   maintable 
       INNER JOIN secondarytable 
               ON maintable.id1 = secondarytable.a_id1 
       INNER JOIN table1 
               ON secondarytable.id2 = table1.id3 
              AND table1.type = '0' 
       INNER JOIN table1 Table1Alias 
               ON secondarytable.id2 = Table1Alias.id3 
              AND Table1Alias.columna = 'conn' 
       INNER JOIN
       ...
WHERE  LEFT(secondarytable.type123, 2) BETWEEN '01' AND '09' 
       AND secondarytable.type456 = 'cate' 
ypercubeᵀᴹ
quelle
ist nicht das WO, das NACH den Verknüpfungen angewendet werden soll, dh ich würde zustimmen, wenn diese Einschränkungen Teil der Verknüpfungsanweisung wären, dh durch ein UND verbunden, aber das WO wird nach aller Erfahrung auf das Ergebnis der Verknüpfung angewendet, aus der Zeilen herausgefiltert werden die verknüpfte Tabelle, ohne die tatsächliche Verknüpfung zu beeinflussen.
Frank Hopkins
3
@Darkwing Soweit ich weiß, spielt es keine Rolle, wo Sie Bedingungen stellen, da es Aufgabe des Abfrageoptimierers ist, den besten Ausführungsplan zu erstellen. Es ist jedoch besser, sie neben Joins zu platzieren, da sie dadurch besser lesbar sind, aber es ist nur eine Meinung
Mathematik
Selbst wenn es NACH dem Beitritt passieren sollte, sind die Ergebnisse der Verknüpfungen am Ende unterschiedlich. Und ja, die verbundenen Zeilen werden normalerweise vor dem Verbinden gefiltert, da dies die Leistung verbessert.
Gherman
1
Dies entspricht auch der Verknüpfung mit einer Unterabfrage, z INNER JOIN (SELECT * FROM table1 WHERE type = 0) table1. Das könnte es noch offensichtlicher machen, was passiert.
Barmar
3
@Mathematics - ob eine Bedingung in der ONKlausel eines Joins oder in der WHEREKlausel enthalten ist, kann sehr wichtig sein, wenn der Join eine ist OUTER JOIN. Wenn eine Bedingung in der ONKlausel fehlschlägt , ist die primäre Zeile weiterhin enthalten (ohne eine übereinstimmende äußere Zeile). Wenn dies in der WHEREKlausel fehlschlägt , wird die primäre Zeile aus der Ergebnismenge ausgeschlossen.
RDFozz
8

Wenn Sie sich die whereKlausel ansehen, muss für die Zeile, auf die von gezeigt wird table1, die Spalte type= '0' und für die Zeile, auf die von gezeigt wird table1alias, die Spalte columna= 'conn' sein.

Vielleicht gibt es mehrere Zeilen table1für dasselbe id3?

Scott Hodgin
quelle
2

Ohne die Tabellenstruktur zu sehen, könnte der Ansatz darin bestehen, einen kleineren nicht abdeckenden Index zu verwenden und dann einen größeren abdeckenden Index in die Tabelle aufzunehmen, um den Rest der Zeilen zu erhalten, um eine 'Key Lookup'-Operation zu vermeiden und vorhandene Indizes nicht zu ändern (oder wenn Sie die Indizes nicht ändern können)

Allan S. Hansen
quelle
2

Wenn eine Tabelle in einem komplexen Join mehrmals vorkommt, liegt dies normalerweise daran, dass eine Entität an mehr als einer Beziehung beteiligt ist. Dies scheint hier der Fall zu sein, gemessen an der Antwort, die @Ypercube gegeben hat.

Entitäten und Beziehungen werden im Allgemeinen durch die Semantik der Daten und die Verbindung zum zugrunde liegenden Gegenstand verstanden. Wenn Ihr Altsystem sorgfältig erstellt wurde, haben sie wahrscheinlich einige Sorgfalt darauf verwendet, das Thema zu analysieren und jedes der Datenelemente sorgfältig zu definieren. Möglicherweise haben sie sogar ein Entity-Relationship-Modell erstellt. All diese sorgfältige Arbeit ist möglicherweise verloren gegangen, und Sie müssen sie nicht mehr rekonstruieren, indem Sie sich in die Vergangenheit vertiefen. Das ist ein bisschen wie Archäologie.

Bei Tabellennamen wie Tabelle1 haben wir keine Ahnung, wie Ihr Thema funktioniert. Und selbst wenn die Namen beschreibend wären, kann sich unser Verständnis des Themas Ihres Systems stark von dem unterscheiden, was in Ihrem Fall benötigt wird. Es wird an dir liegen.

Walter Mitty
quelle