Database
 sql >> Datenbank >  >> RDS >> Database

Lernprogramm für SQL-Joins

Bei einem SQL-Join führen Sie eine Abfrage aus, die mehrere Tabellen verbindet.

Dieses Lernprogramm zu SQL-Joins enthält grundlegende Beispiele für SQL-Joins sowie eine Einführung in die verschiedenen Join-Typen.

SQL-Join-Typen

Der ANSI-SQL-Standard spezifiziert fünf Arten von Joins, die in der folgenden Tabelle aufgeführt sind.

Join-Typ Beschreibung

INNER JOIN
Gibt Zeilen zurück, wenn in beiden Tabellen mindestens eine Zeile vorhanden ist, die der Join-Bedingung entspricht.

LEFT OUTER JOIN
oder
LEFT JOIN
Gibt Zeilen zurück, die Daten in der linken Tabelle enthalten (links vom JOIN). Schlüsselwort), auch wenn es keine übereinstimmenden Zeilen in der rechten Tabelle gibt.

RIGHT OUTER JOIN
oder
RIGHT JOIN
Gibt Zeilen zurück, die Daten in der rechten Tabelle enthalten (rechts vom JOIN). Schlüsselwort), auch wenn es keine übereinstimmenden Zeilen in der linken Tabelle gibt.

FULL OUTER JOIN
oder
FULL JOIN
Gibt alle Zeilen zurück, solange es in einer der Tabellen übereinstimmende Daten gibt.
CROSS JOIN Gibt Zeilen zurück, die jede Zeile aus der ersten Tabelle mit jeder Zeile aus der zweiten Tabelle kombinieren.

Es gibt auch andere Begriffe für verschiedene Join-Operationen, wie zum Beispiel die folgenden:

Beitreten Beschreibung
Self-Join Wenn eine Tabelle mit sich selbst verknüpft wird.
Natürlicher Join Eine implizite Verknüpfung basierend auf den gemeinsamen Spalten in den beiden Tabellen, die verknüpft werden.
Equi-join Ein Join, der nur Gleichheitsvergleiche im Join-Prädikat enthält.

SQL-Join-Syntax

Inner Joins können entweder in FROM angegeben werden oder WHERE Klauseln. Outer Joins und Cross Joins können im FROM angegeben werden nur Klausel.

So erstellen Sie einen SQL-Join im FROM Klausel, machen Sie so etwas:

SELECT *
FROM Table1 < JoinType > Table2 [ ON ( JoinCondition ) ] 

Wobei JoinType gibt an, welche Art von Join durchgeführt wird, und JoinCondition definiert das Prädikat, das für jedes Paar verbundener Zeilen ausgewertet werden soll.

Um einen Join im WHERE anzugeben Klausel, machen Sie so etwas:

SELECT *
FROM Table1, Table2 [ WHERE ( JoinCondition ) ] 

Wieder JoinCondition definiert das Prädikat, das für jedes Paar verbundener Zeilen ausgewertet werden soll.

Auch alles, was in eckige Klammern eingeschlossen ist ([] ) es ist optional.

Beispieltabellen für die Beispiele in diesem Tutorial

Die meisten Beispiele in diesem Tutorial führen Verknüpfungen mit den folgenden zwei Tabellen durch.

Die PetTypes Tabelle:

+-------------+-----------+| PetTypeId | Haustiertyp ||-------------+-----------|| 1 | Vogel || 2 | Katze || 3 | Hund || 4 | Hase |+-------------+-----------+(4 Zeilen betroffen)

Die Pets Tabelle:

+---------+------------+-----------+---------- -+------------+| Haustier-ID | PetTypeId | Eigentümer-ID | Haustiername | Geburtsdatum ||---------+------------+-----------+----------- +------------|| 1 | 2 | 3 | Flauschig | 2020-11-20 || 2 | 3 | 3 | Holen | 2019-08-16 || 3 | 2 | 2 | Kratzer | 01.10.2018 || 4 | 3 | 3 | Wackeln | 2020-03-15 || 5 | 1 | 1 | Twittern | 2020-11-28 || 6 | 3 | 4 | Flauschig | 2020-09-17 || 7 | 3 | 2 | Rinde | NULL || 8 | 2 | 4 | Miau | NULL |+---------+------------+-----------+----------- +------------+(8 Zeilen betroffen)

Der innere Join

Der SQL-INNER JOIN gibt Zeilen zurück, wenn in beiden Tabellen mindestens eine Zeile vorhanden ist, die der Join-Bedingung entspricht.

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
INNER JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId; 

Ergebnis:

-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze |+-----------+-----------+(8 Zeilen betroffen)

Um einen inneren Join im FROM anzugeben -Klausel verwenden wir INNER JOIN . Wir verwenden auch den ON -Schlüsselwort, um das Prädikat zu definieren, das für jedes Paar verbundener Zeilen ausgewertet werden soll.

Unabhängig vom Join-Typ qualifizieren wir unsere Spaltennamen mit den Tabellennamen. Wir tun dies, um Mehrdeutigkeiten bezüglich der Spaltennamen zwischen den Tabellen zu vermeiden. Beide Tabellen könnten Spalten mit demselben Namen haben (wie in unserem Beispiel), und in solchen Fällen weiß das DBMS nicht, auf welche Spalte Sie sich beziehen. Das Präfixieren der Spaltennamen mit ihren Tabellennamen stellt sicher, dass Sie auf die richtige Spalte verweisen, und verhindert Fehler, die aus einer Mehrdeutigkeit darüber resultieren könnten, auf welche Spalte Sie sich beziehen.

In diesem Beispiel haben beide Tabellen eine PetTypeId Säule. Die Pets.PetTypeId Spalte ist ein Fremdschlüssel zu PetTypes.PetTypeId Spalte, die der Primärschlüssel für diese Tabelle ist.

In diesem Beispiel sehen wir, dass alle Haustiere zurückgegeben werden, aber nicht alle Arten von Haustieren. Es gibt keine Kaninchen in den Pets Tabelle, und so die Rabbits Haustiertyp wird nicht zurückgegeben.

Der Grund sind die Rabbits type nicht zurückgegeben wird, weil der INNER JOIN gibt nur Zeilen zurück, wenn in beiden Tabellen mindestens eine Zeile vorhanden ist, die der Join-Bedingung entspricht. In diesem Fall Rabbits befindet sich nur in einer Tabelle (die PetTypes Tabelle).

Beachten Sie, dass der Join-Typ optional ist. Daher erlauben Ihnen die meisten (wenn nicht alle) DBMSs, den INNER wegzulassen Stichwort. Wenn Sie dies weglassen (d. h. nur JOIN angeben ), wird angenommen, dass es sich um eine innere Verknüpfung handelt.

Daher könnten wir das obige Beispiel folgendermaßen umschreiben:

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets
JOIN PetTypes
ON Pets.PetTypeId = PetTypes.PetTypeId; 

Außerdem, wie bei jeder SQL-Anweisung, der FROM Klausel kann auf einer ganzen Zeile stehen, wenn Sie es vorziehen:

SELECT
    Pets.PetName,
    PetTypes.PetType
FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId; 

Aliase

Es ist üblich, beim Ausführen von SQL-Joins Tabellenaliase zu verwenden. Aliase helfen, den Code prägnanter und leichter lesbar zu machen.

Daher könnten wir das vorherige Beispiel wie folgt ändern:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze |+-----------+-----------+(8 Zeilen betroffen)

Der Equi-Join

Der obige Join kann auch als Equi-Join bezeichnet werden . Ein Equi-Join ist ein Join, der nur Gleichheitsvergleiche im Join-Prädikat enthält.

Eine andere Art, den obigen Join zu schreiben, ist wie folgt:

SELECT
    p.PetName,
    pt.PetType
FROM 
    Pets p, 
    PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze |+-----------+-----------+

Dies ist ein Beispiel für die Angabe eines inneren Joins in WHERE Klausel. Wir haben einfach eine durch Kommas getrennte Liste der Tabellen bereitgestellt und dann ein WHERE Zustand. Wenn wir WHERE weggelassen hätten Bedingung, hätten wir am Ende einen CROSS JOIN erhalten .

Viele Anfänger finden die obige Syntax viel einfacher zu verstehen als den INNER JOIN Syntax. Fühlen Sie sich frei, diese Syntax zu verwenden, wenn Sie dies vorziehen, beachten Sie jedoch, dass die meisten SQL-Profis den INNER JOIN bevorzugen Syntax aus dem vorherigen Beispiel.

Weitere Beispiele finden Sie unter SQL Inner Join, einschließlich eines Inner Join, der 3 Tabellen verbindet.

Die richtige Verbindung

Auch als RIGHT OUTER JOIN bekannt , der RIGHT JOIN gibt Zeilen zurück, die Daten in der rechten Tabelle enthalten (rechts vom JOIN). Schlüsselwort), auch wenn es keine übereinstimmenden Zeilen in der linken Tabelle gibt.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Twittern | Vogel || Flauschig | Katze || Kratzer | Katze || Miau | Katze || Holen | Hund || Wackeln | Hund || Flauschig | Hund || Rinde | Hund || NULL | Hase |+-----------+-----------+(9 Zeilen betroffen)

In diesem Fall haben wir einen zusätzlichen PetType Wert – Rabbits – obwohl es kein Haustier in den Pets gibt Tabelle dieser Art. Dies führt zu einem NULL Wert im PetName Spalte gegen Rabbit .

Weitere Beispiele finden Sie unter SQL Right Join, einschließlich eines Right Join, der 3 Tabellen verbindet.

Die linke Verbindung

Auch als LEFT OUTER JOIN bekannt , der SQL LEFT JOIN gibt Zeilen zurück, die Daten in der linken Tabelle enthalten (links vom JOIN). Schlüsselwort), auch wenn es keine übereinstimmenden Zeilen in der rechten Tabelle gibt.

Dies ist das Gegenteil von RIGHT JOIN .

Wenn wir das vorherige Beispiel ändern, um einen linken Join zu verwenden, erhalten wir das folgende Ergebnis.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
LEFT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze |+-----------+-----------+(8 Zeilen betroffen)

In diesem speziellen Fall sind unsere Ergebnisse die gleichen wie beim Inner Join.

Wenn wir jedoch die Tabellenreihenfolge in unserem FROM vertauschen -Klausel erhalten wir ein ähnliches Ergebnis wie beim rechten Join im vorherigen Beispiel.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
LEFT JOIN Pets p
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Twittern | Vogel || Flauschig | Katze || Kratzer | Katze || Miau | Katze || Holen | Hund || Wackeln | Hund || Flauschig | Hund || Rinde | Hund || NULL | Hase |+-----------+-----------+(9 Zeilen betroffen)

Sie können also sehen, dass jeder resultierende Unterschied zwischen den Links- und Rechtsverknüpfungen ausschließlich davon abhängt, wie Sie die Spalten in FROM anordnen Klausel.

Weitere Beispiele finden Sie unter SQL Left Join, einschließlich eines Left Join, der 3 Tabellen verbindet.

Der vollständige Beitritt

Der SQL-FULL JOIN (oder FULL OUTER JOIN ) gibt alle Zeilen zurück, solange in einer der Tabellen übereinstimmende Daten vorhanden sind.

Mit anderen Worten, es ist, als hätte man sowohl einen linken als auch einen rechten Join in einem Join.

Hier ist ein Beispiel für einen vollständigen Join.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze || NULL | Hase |+-----------+-----------+(9 Zeilen betroffen)

Dies gibt das gleiche Ergebnis zurück, das wir mit dem rechten Join erhalten haben, aber es hätte ein anderes Ergebnis zurückgegeben, wenn es eine Zeile in der linken Tabelle gegeben hätte, die keinen entsprechenden Wert in der rechten Tabelle hätte.

Lassen Sie uns die Tabellennamen vertauschen und es erneut ausführen.

SELECT 
    p.PetName,
    pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Twittern | Vogel || Flauschig | Katze || Kratzer | Katze || Miau | Katze || Holen | Hund || Wackeln | Hund || Flauschig | Hund || Rinde | Hund || NULL | Hase |+-----------+-----------+(9 Zeilen betroffen)

Gleiches Ergebnis.

Weitere Beispiele finden Sie unter Vollständiger SQL-Join, einschließlich eines vollständigen Joins, der 3 Tabellen verbindet.

Die Kreuzverbindung

Der SQL-CROSS JOIN gibt Zeilen zurück, die jede Zeile aus der ersten Tabelle mit jeder Zeile aus der zweiten Tabelle kombinieren.

Mit anderen Worten, es gibt das kartesische Produkt von Zeilen aus Tabellen im Join zurück.

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Vogel || Holen | Vogel || Kratzer | Vogel || Wackeln | Vogel || Twittern | Vogel || Flauschig | Vogel || Rinde | Vogel || Miau | Vogel || Flauschig | Katze || Holen | Katze || Kratzer | Katze || Wackeln | Katze || Twittern | Katze || Flauschig | Katze || Rinde | Katze || Miau | Katze || Flauschig | Hund || Holen | Hund || Kratzer | Hund || Wackeln | Hund || Twittern | Hund || Flauschig | Hund || Rinde | Hund || Miau | Hund || Flauschig | Kaninchen || Holen | Kaninchen || Kratzer | Kaninchen || Wackeln | Kaninchen || Twittern | Kaninchen || Flauschig | Kaninchen || Rinde | Kaninchen || Miau | Kaninchen |+-----------+-----------+(32 Zeilen betroffen)

Wie Sie sich wahrscheinlich vorstellen können, könnte dies sehr gefährlich sein, wenn Sie es gegen die falschen Tische laufen lassen.

Es ist dasselbe wie dies:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p, PetTypes pt; 

Sie können ein WHERE hinzufügen -Klausel zu einem Cross-Join, wodurch sie in einen Inner-Join umgewandelt wird.

So:

SELECT 
    p.PetName,
    pt.PetType
FROM Pets p
CROSS JOIN PetTypes pt
WHERE p.PetTypeId = pt.PetTypeId; 

Ergebnis:

+-----------+-----------+| Haustiername | Haustiertyp ||-----------+-----------|| Flauschig | Katze || Holen | Hund || Kratzer | Katze || Wackeln | Hund || Twittern | Vogel || Flauschig | Hund || Rinde | Hund || Miau | Katze |+-----------+-----------+(8 Zeilen betroffen)

Weitere Beispiele finden Sie unter SQL Cross Join.

Die natürliche Verbindung

Der SQL-NATURAL JOIN ist eine Art Equi-Join, bei dem das Join-Prädikat implizit entsteht, indem alle Spalten in beiden Tabellen verglichen werden, die in den verknüpften Tabellen dieselben Spaltennamen haben.

Die Ergebnismenge enthält nur eine Spalte für jedes Paar gleichnamiger Spalten. Wenn keine Spalten mit demselben Namen gefunden werden, ist das Ergebnis ein Cross Join.

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL JOIN PetTypes; 

Ergebnis:

Hausname | pettype ---------+--------- Fluffy | Katze holen | Hund kratzen | Katze wedelt | Hund twittern | Vogel flauschig | Hund bellen | Hund Miau | Katze (8 Reihen)

Tatsächlich ist der natürliche Join kein Join-Typ im Sinne des ANSI-Standards. Es ist ein Schlüsselwort, das Sie optional einfügen können, um den Join zu einem natürlichen Join zu machen.

Daher könnten wir das obige Beispiel in NATURAL INNER JOIN ändern wenn wir wollten:

SELECT 
    Pets.PetName,
    PetTypes.PetType
FROM Pets NATURAL INNER JOIN PetTypes; 

Wie bereits erwähnt, sind innere Joins der Standard-Join-Typ, wenn Sie also den Join-Typ weglassen (z. B. INNER , LEFT , RIGHT usw.), dann wird es als innerer Join behandelt.

Wenn die Formatierung dieser Ergebnisse anders aussieht als die vorherigen Ergebnisse, liegt das daran, dass ich zu PostgreSQL wechseln musste, um diese Abfrage auszuführen. Ich habe die vorherigen Beispiele in SQL Server ausgeführt, aber SQL Server unterstützt die natürliche Verknüpfung nicht.

Siehe SQL Natural Join für weitere Beispiele, einschließlich eines natürlichen Joins, der 3 Tabellen verbindet.

Der Selbstbeitritt

Der SQL-SELF JOIN verbindet eine Tabelle mit sich selbst.

Ein klassisches Beispiel für einen Self-Join ist eine Employees-Tabelle. In einer solchen Tabelle kann ein Mitarbeiter einem anderen Mitarbeiter unterstellt sein. Daher könnten Sie einen Self-Join verwenden, um die Tabelle in der Spalte "Mitarbeiter-ID" und "Manager-ID" zu verknüpfen.

Angenommen, wir haben die folgende Tabelle:

+--------------+------------+------------+---- ---------+| MitarbeiterID | Vorname | Nachname | BerichteAn ||--------------+------------+------------+----- --------|| 1 | Homer | Conner | NULL || 2 | Bart | Pitt | 1 || 3 | Maggie | Greif | 1 || 4 | Peter | Farnworth | 2 || 5 | Marge | Morrison | NULL || 6 | Lisa | Stapel | 5 || 7 | David | Zuckerberg | 6 || 8 | Vlad | Koch | 7 |+--------------+------------+------------+----- --------+

Wir können an dieser Tabelle eine Selbstverknüpfung durchführen, um alle Mitarbeiter und ihre Manager zurückzugeben.

SELECT
    CONCAT(e1.FirstName, ' ', e1.LastName) AS Employee,
    CONCAT(e2.FirstName, ' ', e2.LastName) AS Manager
FROM Employees e1
LEFT JOIN Employees e2 
ON e1.ReportsTo = e2.EmployeeId; 

Ergebnis:

+------------------+-----------------+| Mitarbeiter | Manager ||-----------------+-----------------|| Homer Connery | || Bart Pitt | Homer Connery || Maggie Griffin | Homer Connery || Peter Farnsworth | Bart Pitt || Marge Morrison | || Lisa-Batch | Marge Morrison || David Zuckerberg | Lisa-Batch || Vlad Koch | Dave Zuckerberg |+-----------------+----------------+

Weitere Beispiele finden Sie unter SQL Self Join.