Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Drei-Tabellen-Join mit anderen Joins als INNER JOIN

Ja, ich verwende alle drei dieser JOINs, obwohl ich dazu neige, nur LEFT (OUTER) JOIN zu verwenden s, anstatt LEFT- und RIGHT JOINs zu mischen. Ich verwende auch FULL OUTER JOIN s und CROSS JOIN s.

Zusammenfassend ein INNER JOIN schränkt die Ergebnismenge nur auf die Datensätze ein, die von der JOIN-Bedingung erfüllt werden. Betrachten Sie die folgenden Tabellen

BEARBEITEN: Ich habe die Tabellennamen umbenannt und ihnen @ vorangestellt damit Tabellenvariablen für jeden verwendet werden können, der diese Antwort liest und experimentieren möchte.

Wenn Sie auch damit im Browser experimentieren möchten, ich habe das alles auf SQL Fiddle eingerichtet auch;

@Table1

id | name
---------
1  | One
2  | Two
3  | Three
4  | Four

@Table2

id | name
---------
1  | Partridge
2  | Turtle Doves
3  | French Hens
5  | Gold Rings

SQL-Code

DECLARE @Table1 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table1 VALUES(1, 'One');
INSERT INTO @Table1 VALUES(2, 'Two');
INSERT INTO @Table1 VALUES(3, 'Three');
INSERT INTO @Table1 VALUES(4, 'Four');

DECLARE @Table2 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table2 VALUES(1, 'Partridge');
INSERT INTO @Table2 VALUES(2, 'Turtle Doves');
INSERT INTO @Table2 VALUES(3, 'French Hens');
INSERT INTO @Table2 VALUES(5, 'Gold Rings');

Ein INNER JOIN SQL-Anweisung, verknüpft mit id Feld

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Ergibt

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens

Ein LEFT JOIN gibt eine Ergebnismenge mit allen Datensätzen aus der Tabelle auf der linken Seite des Joins zurück (wenn Sie die Anweisung als Einzeiler schreiben, die Tabelle, die zuerst angezeigt wird) und Felder aus der Tabelle auf der rechten Seite des Joins die mit dem Join-Ausdruck übereinstimmen und in SELECT enthalten sind Klausel. Fehlt Details werden mit NULL ausgefüllt

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
LEFT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Ergebnisse in

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
4  | Four | NULL

Ein RIGHT JOIN ist die gleiche Logik wie ein LEFT JOIN gibt aber alle Datensätze von der rechten Seite des Joins und Felder von der linken Seite zurück, die mit dem Join-Ausdruck übereinstimmen und in SELECT enthalten sind Klausel.

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
RIGHT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Ergebnisse in

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
NULL| NULL| Gold Rings

Natürlich gibt es auch den FULL OUTER JOIN , das Datensätze aus beiden verknüpften Tabellen enthält und alle fehlenden auffüllt Details mit NULL.

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
FULL OUTER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id

Ergebnisse in

id | name | name
----------------
1  | One  | Partridge
2  | Two  | Turtle Doves
3  | Three| French Hens
4  | Four | NULL
NULL| NULL| Gold Rings

Und ein CROSS JOIN (auch als CARTESIAN PRODUCT bekannt ), was einfach das Produkt der Kreuzanwendung von Feldern in SELECT ist Anweisung aus einer Tabelle mit den Feldern im SELECT Aussage von der anderen Tabelle. Beachten Sie, dass es in einem CROSS JOIN keinen Join-Ausdruck gibt

SELECT 
    t1.id,
    t1.name,
    t2.name
FROM
    @Table1 t1
CROSS JOIN
    @Table2 t2

Ergibt

id | name  | name
------------------
1  | One   | Partridge
2  | Two   | Partridge
3  | Three | Partridge
4  | Four  | Partridge
1  | One   | Turtle Doves
2  | Two   | Turtle Doves
3  | Three | Turtle Doves
4  | Four  | Turtle Doves
1  | One   | French Hens
2  | Two   | French Hens
3  | Three | French Hens
4  | Four  | French Hens
1  | One   | Gold Rings
2  | Two   | Gold Rings
3  | Three | Gold Rings
4  | Four  | Gold Rings

BEARBEITEN:

Stellen Sie sich vor, es gäbe jetzt eine Tabelle3

@Table3

id | name
---------
2  | Prime 1
3  | Prime 2
5  | Prime 3

Der SQL-Code

DECLARE @Table3 TABLE (id INT PRIMARY KEY CLUSTERED, [name] VARCHAR(25))

INSERT INTO @Table3 VALUES(2, 'Prime 1');
INSERT INTO @Table3 VALUES(3, 'Prime 2');
INSERT INTO @Table3 VALUES(5, 'Prime 3');

Jetzt sind alle drei Tabellen mit INNER JOINS verbunden

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
INNER JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Ergebnisse in

id | name | name         | name
-------------------------------
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2

Es könnte hilfreich sein, dieses Ergebnis zu verstehen, wenn man bedenkt, dass Datensätze mit den IDs 2 und 3 die einzigen sind, die allen 3 Tabellen und gemeinsam sind sind auch das Feld, auf dem wir jeden Tisch beitreten.

Jetzt alle drei mit LEFT JOINS

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
LEFT JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
LEFT JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Ergebnisse in

id | name | name         | name
-------------------------------
1  | One  | Partridge    | NULL
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2
4  | Four | NULL         | NULL

Joels Antwort ist eine gute Erklärung für die Erklärung dieser Ergebnismenge (Tabelle1 ist die Basis-/Ursprungstabelle).

Jetzt mit einem INNER JOIN und ein LEFT JOIN

SELECT 
    t1.id,
    t1.name,
    t2.name,
    t3.name
FROM
    @Table1 t1
INNER JOIN
    @Table2 t2
    ON 
        t1.id = t2.id
LEFT JOIN
    @Table3 t3
    ON 
        t1.id = t3.id

Ergebnisse in

id | name | name         | name
-------------------------------
1  | One  | Partridge    | NULL
2  | Two  | Turtle Doves | Prime 1
3  | Three| French Hens  | Prime 2

Obwohl wir die Reihenfolge nicht kennen, in der der Abfrageoptimierer die Operationen ausführt, werden wir diese Abfrage von oben nach unten betrachten, um die Ergebnismenge zu verstehen. Der INNER JOIN on ids between Table1 and Table2 schränkt die Ergebnismenge auf nur die Datensätze ein, die von der Join-Bedingung erfüllt werden, d. h. die drei Zeilen, die wir im allerersten Beispiel gesehen haben. Dies vorübergehend resultset ist dann LEFT JOIN ed zu Table3 auf IDs zwischen Table1 und Tables; Es gibt Datensätze in Tabelle 3 mit den IDs 2 und 3, aber nicht mit der ID 1, also enthält das Feld t3.name Details für 2 und 3, aber nicht für 1.