Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Łączenie trzech stołów z łączeniami innymi niż INNER JOIN

Tak, używam wszystkich trzech JOIN, chociaż zwykle trzymam się tylko LEFT (OUTER) JOIN zamiast mieszać lewe i prawe JOIN. Używam również FULL OUTER JOIN s i CROSS JOIN s.

Podsumowując, INNER JOIN ogranicza zestaw wyników tylko do tych rekordów, które spełniają warunek JOIN. Rozważ następujące tabele

EDYTUJ: Zmieniłem nazwy tabel i poprzedziłem je @ aby zmienne tabeli mogły być używane przez każdego, kto czyta tę odpowiedź i chce poeksperymentować.

Jeśli chcesz poeksperymentować z tym w przeglądarce, ustawiłem to wszystko w SQL Fiddle też;

@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

Kod SQL

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');

INNER JOIN Instrukcja SQL, dołączona do id pole

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

Wyniki w

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

LEFT JOIN zwróci zestaw wyników ze wszystkimi rekordami z tabeli po lewej stronie złączenia (jeżeli miałbyś napisać instrukcję jako jedną linijkę, tabela, która pojawia się jako pierwsza) oraz pola z tabeli po prawej stronie złączenia które pasują do wyrażenia sprzężenia i są zawarte w SELECT klauzula. Brak szczegóły zostaną wypełnione NULL

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

Wyniki w

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

RIGHT JOIN jest taka sama jak logika LEFT JOIN ale zwróci wszystkie rekordy z prawej strony złączenia i pola z lewej strony, które pasują do wyrażenia złączenia i są zawarte w SELECT klauzula.

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

Wyniki w

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

Oczywiście istnieje również FULL OUTER JOIN , który zawiera rekordy z obu połączonych tabel i wypełnia wszystkie brakujące szczegóły z NULL.

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

Wyniki w

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

Oraz CROSS JOIN (znany również jako CARTESIAN PRODUCT ), który jest po prostu produktem krzyżowego stosowania pól w SELECT oświadczenie z jednej tabeli z polami w SELECT oświadczenie z drugiej tabeli. Zauważ, że nie ma wyrażenia złączenia w CROSS JOIN

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

Wyniki w

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

EDYTUJ:

Wyobraź sobie, że jest teraz Tabela3

@Table3

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

Kod SQL

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');

Teraz wszystkie trzy tabele połączone za pomocą INNER JOINS

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

Wyniki w

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

Zrozumienie tego wyniku może pomóc, myśląc, że rekordy o identyfikatorach 2 i 3 są jedynymi wspólnymi dla wszystkich 3 tabel i są również polem, na którym dołączamy do każdego stołu.

Teraz wszystkie trzy z 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

Wyniki w

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

Odpowiedź Joela jest dobrym wyjaśnieniem tego zestawu wyników (Tabela 1 jest tabelą bazową/początkową).

Teraz z INNER JOIN i 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

Wyniki w

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

Chociaż nie znamy kolejności, w jakiej optymalizator zapytań wykona operacje, przyjrzymy się temu zapytaniu od góry do dołu, aby zrozumieć zestaw wyników. INNER JOIN on ids pomiędzy Table1 i Table2 ograniczy zestaw wyników tylko do tych rekordów, które spełniają warunek złączenia, tj. do trzech wierszy, które widzieliśmy w pierwszym przykładzie. Ten tymczasowy zestaw wyników będzie wtedy LEFT JOIN ed do Tabeli 3 na identyfikatory między Tabelą 1 a Tabelami; W tabeli 3 znajdują się rekordy o identyfikatorach 2 i 3, ale nie o identyfikatorze 1, więc pole t3.name będzie zawierało szczegóły dla 2 i 3, ale nie 1.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Dlaczego select SCOPE_IDENTITY() zwraca liczbę dziesiętną zamiast liczby całkowitej?

  2. Klauzula ORDER BY jest nieprawidłowa w widokach, funkcjach wbudowanych, tabelach pochodnych, podzapytaniach i typowych wyrażeniach tabelowych

  3. Znajdowanie zduplikowanych wierszy w SQL Server

  4. Nie mogę uruchomić przeglądarki SQL Server

  5. Know-How przywracania usuniętych rekordów w SQL Server