Ein innerer Join erfordert, dass jede Zeile in den beiden verbundenen Tabellen übereinstimmende Spaltenwerte aufweist. Dies ist eine häufig verwendete Join-Operation in Anwendungen, sollte jedoch nicht als die beste Wahl angesehen werden in allen Situationen. Inner Join erstellt eine neue Ergebnistabelle, indem Spaltenwerte von zwei Tabellen (A und B) basierend auf dem Join-Prädikat kombiniert werden. Die Abfrage vergleicht jede Zeile von A mit jeder Zeile von B, um alle Zeilenpaare zu finden, die das Join-Prädikat erfüllen. Wenn das Join-Prädikat durch Abgleichen von Nicht-NULL-Werten erfüllt ist, werden Spaltenwerte für jedes übereinstimmende Zeilenpaar von A und B zu einer Ergebniszeile kombiniert.
Das Ergebnis des Joins kann als definiert werden Ergebnis der ersten Verwendung des kartesischen Produkts (oder Cross-Joins) aller Zeilen in den Tabellen (Kombination jeder Zeile in Tabelle A mit jeder Zeile in Tabelle B) und anschließender Rückgabe aller Zeilen, die das Join-Prädikat erfüllen. Tatsächliche SQL-Implementierungen verwenden normalerweise andere Ansätze, wie z. B. Hash-Joins oder Sort-Merge-Joins, da die Berechnung des kartesischen Produkts langsamer ist und häufig eine unerschwinglich große Speichermenge zum Speichern erfordert.
SQL gibt zwei verschiedene syntaktische Methoden an Möglichkeiten, Joins auszudrücken: die „explizite Join-Notation“ und die „implizite Join-Notation“. Die „implizite Join-Notation“ wird nicht mehr als bewährte Methode angesehen, obwohl Datenbanksysteme sie weiterhin unterstützen.
Die „explizite Join-Notation“ verwendet das Schlüsselwort JOIN
. Optional wird das Schlüsselwort INNER
vorangestellt, um die zu verbindende Tabelle anzugeben, und das Schlüsselwort ON
, um die Prädikate für den Join anzugeben, wie in das folgende Beispiel:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee INNER JOIN department ONemployee.DepartmentID = department.DepartmentID;
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
Büroangestellter |
Jones |
33 |
Engineering |
Smith |
34 |
Büroangestellter |
Heisenberg |
33 |
Engineering |
Rafferty |
31 |
Vertrieb |
Die „implizite Join-Notation“ listet einfach t auf Die Tabellen zum Verbinden werden in der FROM
-Klausel der SELECT
-Anweisung durch Kommas getrennt. Daher wird eine Kreuzverknüpfung angegeben, und die WHERE
-Klausel kann zusätzliche Filterprädikate anwenden (die vergleichbar mit den Verknüpfungsprädikaten in der expliziten Notation funktionieren).
Das folgende Beispiel entspricht dem vorherigen, diesmal jedoch mit impliziter Join-Notation:
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Die in den Beispielen angegebenen Abfragen Oben werden die Mitarbeiter- und Abteilungstabellen mithilfe der Spalte DepartmentID beider Tabellen verknüpft. Wenn die DepartmentID dieser Tabellen übereinstimmt (d. H. Das Join-Prädikat ist erfüllt), kombiniert die Abfrage die Spalten LastName, DepartmentID und DepartmentName aus den beiden Tabellen zu einer Ergebniszeile. Wenn die DepartmentID nicht übereinstimmt, wird keine Ergebniszeile generiert.
Das Ergebnis der Ausführung der obigen Abfrage lautet also:
Employee.LastName |
Employee.DepartmentID |
Department.DepartmentName |
Robinson |
34 |
Büroangestellter |
Jones |
33 |
Ingenieurwesen |
Smith |
34 |
Büro |
Heisenberg |
33 |
Engineering |
Rafferty |
31 |
Vertrieb |
Der Mitarbeiter „Williams“ und die Abteilung „Marketing“ werden in den Ergebnissen der Abfrageausführung nicht angezeigt. Keine dieser Zeilen enthält übereinstimmende Zeilen in der jeweiligen Tabelle: „Williams“ hat keine zugeordnete Abteilung, und kein Mitarbeiter hat die Abteilungs-ID 35 („Marketing“). Abhängig von den gewünschten Ergebnissen kann dieses Verhalten ein subtiler Fehler sein, der vermieden werden kann, indem der innere Join durch einen äußeren Join ersetzt wird.
Innerer Join und NULL-WerteEdit
Programmierer sollten dies tun Besondere Vorsicht beim Verknüpfen von Tabellen in Spalten, die NULL-Werte enthalten können, da NULL niemals mit einem anderen Wert übereinstimmt (nicht einmal mit NULL selbst), es sei denn, die Verknüpfungsbedingung verwendet explizit ein Kombinationsprädikat, das zuerst überprüft, ob die Verknüpfungsspalten , bevor die verbleibenden Prädikatbedingungen angewendet werden. Der innere Join kann nur sicher in einer Datenbank verwendet werden, die die referenzielle Integrität erzwingt oder in der die Join-Spalten garantiert nicht NULL sind. Viele relationale Datenbanken für die Transaktionsverarbeitung basieren auf ACID-Standards (Atomicity, Consistency, Isolation, Durability), um die Datenintegrität sicherzustellen und innere Verknüpfungen zu einer geeigneten Wahl zu machen. Transaktionsdatenbanken haben jedoch normalerweise auch wünschenswerte Verknüpfungsspalten, die NULL sein dürfen.Viele relationale Datenbank- und Data Warehouses für die Berichterstellung verwenden ETL-Stapelaktualisierungen (Extract, Transform, Load) mit hohem Volumen, die die Durchsetzung der referenziellen Integrität erschweren oder unmöglich machen. Dies führt zu potenziell NULL-Join-Spalten, die ein SQL-Abfrageautor nicht ändern kann und die dazu führen, dass innere Joins weggelassen werden Daten ohne Hinweis auf einen Fehler. Die Wahl eines inneren Joins hängt vom Datenbankdesign und den Dateneigenschaften ab. Ein linker äußerer Join kann normalerweise einen inneren Join ersetzen, wenn die Join-Spalten in einer Tabelle NULL-Werte enthalten können.
Eine Datenspalte, die NULL (leer) sein kann, sollte niemals als Link in einem verwendet werden innerer Join, es sei denn, das beabsichtigte Ergebnis besteht darin, die Zeilen mit dem NULL-Wert zu entfernen. Wenn NULL-Join-Spalten absichtlich aus der Ergebnismenge entfernt werden sollen, kann ein innerer Join schneller sein als ein äußerer Join, da der Tabellen-Join und die Filterung in einem einzigen Schritt erfolgen. Umgekehrt kann ein innerer Join zu einer katastrophal langsamen Leistung oder sogar zu einem Serverabsturz führen, wenn er in einer Abfrage mit großem Volumen in Kombination mit Datenbankfunktionen in einer SQL Where-Klausel verwendet wird. Eine Funktion in einer SQL Where-Klausel kann dazu führen, dass die Datenbank relativ kompakte Tabellenindizes ignoriert. Die Datenbank kann die ausgewählten Spalten aus beiden Tabellen lesen und innerlich verknüpfen, bevor die Anzahl der Zeilen mithilfe des Filters verringert wird, der von einem berechneten Wert abhängt, was zu einer relativ enormen Menge ineffizienter Verarbeitung führt.
Wenn eine Ergebnismenge wird durch Zusammenfügen mehrerer Tabellen erzeugt, einschließlich Mastertabellen, die zum Nachschlagen von Volltextbeschreibungen numerischer Bezeichnercodes (eine Nachschlagetabelle) verwendet werden. Ein NULL-Wert in einem der Fremdschlüssel kann dazu führen, dass die gesamte Zeile aus der Ergebnismenge entfernt wird. ohne Fehleranzeige. Eine komplexe SQL-Abfrage, die eine oder mehrere innere Verknüpfungen und mehrere äußere Verknüpfungen enthält, birgt das gleiche Risiko für NULL-Werte in den inneren Verknüpfungsverbindungsspalten.
Bei einer Zusage für SQL-Code, der innere Verknüpfungen enthält, wird davon ausgegangen, dass NULL-Verknüpfungsspalten dies nicht tun durch zukünftige Änderungen eingeführt werden, einschließlich Herstelleraktualisierungen, Designänderungen und Massenverarbeitung außerhalb der Datenvalidierungsregeln der Anwendung wie Datenkonvertierungen, Migrationen, Massenimporte und -zusammenführungen.
Man kann innere Verknüpfungen weiter klassifizieren als Equi-Joins, als natürliche Joins oder als Cross-Joins.
Equi-joinEdit
Ein Equi-Join ist ein bestimmter Typ eines komparatorbasierten Joins, der nur Gleichheitsvergleiche verwendet Wenn Sie andere Vergleichsoperatoren verwenden (z. B. <
), wird ein Join als Equi-Join disqualifiziert. Die oben gezeigte Abfrage enthält bereits ein Beispiel für einen Equi-Join:
SELECT *FROM employee JOIN department ON employee.DepartmentID = department.DepartmentID;
Wir können Equi-Join wie folgt schreiben:
SELECT *FROM employee, departmentWHERE employee.DepartmentID = department.DepartmentID;
Wenn co Spalten in einem Equi-Join haben denselben Namen. SQL-92 bietet eine optionale Kurzschreibweise zum Ausdrücken von Equi-Joins über das Konstrukt USING
:
SELECT
read more