Database
 sql >> Baza danych >  >> RDS >> Database

Samouczek łączenia SQL

Sprzężenie SQL polega na uruchomieniu zapytania, które łączy wiele tabel.

W tym samouczku dotyczącym złączeń SQL przedstawiono podstawowe przykłady złączeń SQL, a także wprowadzenie do różnych typów złączeń.

Typy złączeń SQL

Standard ANSI SQL określa pięć typów złączeń wymienionych w poniższej tabeli.

Typ łączenia Opis

INNER JOIN
Zwraca wiersze, gdy w obu tabelach jest co najmniej jeden wiersz, który spełnia warunek złączenia.

LEFT OUTER JOIN
lub
LEFT JOIN
Zwraca wiersze, które mają dane w lewej tabeli (po lewej stronie JOIN słowa kluczowego), nawet jeśli w prawej tabeli nie ma pasujących wierszy.

RIGHT OUTER JOIN
lub
RIGHT JOIN
Zwraca wiersze, które zawierają dane w prawej tabeli (na prawo od JOIN słowa kluczowego), nawet jeśli w lewej tabeli nie ma pasujących wierszy.

FULL OUTER JOIN
lub
FULL JOIN
Zwraca wszystkie wiersze, o ile w jednej z tabel znajdują się pasujące dane.
CROSS JOIN Zwraca wiersze, które łączą każdy wiersz z pierwszej tabeli z każdym wierszem z drugiej tabeli.

Istnieją również inne terminy dla różnych operacji łączenia, takie jak:

Dołącz Opis
Dołącz samodzielnie Kiedy tabela łączy się ze sobą.
Naturalne połączenie Złączenie niejawne oparte na wspólnych kolumnach w dwóch łączonych tabelach.
Łączenie równo Złączenie zawierające tylko porównania równości w predykacie złączenia.

Składnia łączenia SQL

Sprzężenia wewnętrzne można określić w FROM lub WHERE klauzule. Złącza zewnętrzne i sprzężenia krzyżowe można określić w FROM tylko klauzula.

Aby utworzyć sprzężenie SQL w FROM klauzula, zrób coś takiego:

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

Gdzie JoinType określa, jaki rodzaj łączenia jest wykonywany, a JoinCondition definiuje predykat do oceny dla każdej pary połączonych wierszy.

Aby określić sprzężenie w WHERE klauzula, zrób coś takiego:

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

Ponownie, JoinCondition definiuje predykat do oceny dla każdej pary połączonych wierszy.

Ponadto wszystko ujęte w nawiasy kwadratowe ([] ) jest opcjonalne.

Przykładowe tabele dla przykładów w tym samouczku

Większość przykładów w tym samouczku wykonuje sprzężenia w poniższych dwóch tabelach.

PetTypes tabela:

+-------------+-----------+
| PetTypeId   | PetType   |
|-------------+-----------|
| 1           | Bird      |
| 2           | Cat       |
| 3           | Dog       |
| 4           | Rabbit    |
+-------------+-----------+
(4 rows affected)

Pets tabela:

+---------+-------------+-----------+-----------+------------+
| PetId   | PetTypeId   | OwnerId   | PetName   | DOB        |
|---------+-------------+-----------+-----------+------------|
| 1       | 2           | 3         | Fluffy    | 2020-11-20 |
| 2       | 3           | 3         | Fetch     | 2019-08-16 |
| 3       | 2           | 2         | Scratch   | 2018-10-01 |
| 4       | 3           | 3         | Wag       | 2020-03-15 |
| 5       | 1           | 1         | Tweet     | 2020-11-28 |
| 6       | 3           | 4         | Fluffy    | 2020-09-17 |
| 7       | 3           | 2         | Bark      | NULL       |
| 8       | 2           | 4         | Meow      | NULL       |
+---------+-------------+-----------+-----------+------------+
(8 rows affected)

Łączenie wewnętrzne

SQL INNER JOIN zwraca wiersze, gdy w obu tabelach jest co najmniej jeden wiersz, który spełnia warunek złączenia.

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

Wynik:

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Aby określić sprzężenie wewnętrzne w FROM klauzula, używamy INNER JOIN . Używamy również ON słowo kluczowe, aby zdefiniować predykat do oceny dla każdej pary połączonych wierszy.

Niezależnie od typu sprzężenia kwalifikujemy nazwy naszych kolumn nazwami tabel. Powodem, dla którego to robimy, jest uniknięcie niejasności dotyczących nazw kolumn między tabelami. Obie tabele mogą mieć kolumny o tej samej nazwie (jak w naszym przykładzie), a w takich przypadkach DBMS nie będzie wiedział, do której kolumny się odnosisz. Poprzedzenie nazw kolumn ich nazwami tabel gwarantuje, że odwołujesz się do właściwej kolumny i zapobiega wszelkim błędom, które mogą wynikać z jakichkolwiek niejasności co do kolumny, do której się odnosisz.

W tym przykładzie obie tabele mają PetTypeId kolumna. Pets.PetTypeId kolumna jest kluczem obcym do PetTypes.PetTypeId kolumna, która jest kluczem podstawowym dla tej tabeli.

W tym przykładzie widzimy, że zwracane są wszystkie zwierzęta, ale nie wszystkie typy zwierząt. W Pets nie ma królików tabela, a więc Rabbits typ zwierzaka nie jest zwracany.

Powód, dla którego Rabbits typ nie jest zwracany, ponieważ INNER JOIN zwraca wiersze tylko wtedy, gdy w obu tabelach znajduje się co najmniej jeden wiersz, który spełnia warunek złączenia. W tym przypadku Rabbits znajduje się tylko w jednej tabeli (PetTypes tabeli).

Zauważ, że typ łączenia jest opcjonalny. Dlatego większość (jeśli nie wszystkie) DBMS pozwala na pominięcie INNER słowo kluczowe. Gdy to pominiesz (tzn. określ tylko JOIN ), zakłada się, że jest to sprzężenie wewnętrzne.

Dlatego możemy przepisać powyższy przykład do tego:

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

Podobnie jak w przypadku każdej instrukcji SQL, FROM klauzula może znajdować się w jednym wierszu, jeśli wolisz:

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

Aliasy

Powszechną praktyką jest używanie aliasów tabel podczas wykonywania złączeń SQL. Aliasy pomagają uczynić kod bardziej zwięzłym i łatwiejszym do odczytania.

Dlatego możemy zmienić poprzedni przykład na następujący:

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

Wynik:

-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Złączenie równoprawne

Powyższe złączenie może być również określane jako equi-join . Złączenie ekwiwalentne to złączenie zawierające tylko porównania równości w predykacie złączenia.

Inny sposób napisania powyższego sprzężenia jest taki:

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+

To jest przykład określenia sprzężenia wewnętrznego w WHERE klauzula. Po prostu dostarczyliśmy listę tabel oddzielonych przecinkami, a następnie WHERE stan :schorzenie. Gdybyśmy pominęli WHERE warunek, otrzymalibyśmy CROSS JOIN .

Dla wielu początkujących powyższa składnia jest znacznie łatwiejsza do zrozumienia niż INNER JOIN składnia. Możesz użyć tej składni, jeśli wolisz, jednak pamiętaj, że większość specjalistów SQL woli używać INNER JOIN składnia z poprzedniego przykładu.

Zobacz SQL Inner Join, aby uzyskać więcej przykładów, w tym złącze wewnętrzne, które łączy 3 tabele.

Właściwe połączenie

Znany również jako RIGHT OUTER JOIN , RIGHT JOIN zwraca wiersze, które mają dane w prawej tabeli (na prawo od JOIN słowa kluczowego), nawet jeśli w lewej tabeli nie ma pasujących wierszy.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

W tym przypadku otrzymaliśmy dodatkowy PetType wartość – Rabbit – mimo że nie ma zwierzaka w Pets tabeli tego typu. Powoduje to NULL wartość w PetName kolumna przeciwko Rabbit .

Zobacz SQL Right Join, aby uzyskać więcej przykładów, w tym prawego sprzężenia, które łączy 3 tabele.

Lewe połączenie

Znany również jako LEFT OUTER JOIN , SQL LEFT JOIN zwraca wiersze, które mają dane w lewej tabeli (po lewej stronie JOIN słowa kluczowego), nawet jeśli w prawej tabeli nie ma pasujących wierszy.

Jest to przeciwieństwo RIGHT JOIN .

Jeśli zmienimy poprzedni przykład na użycie lewego sprzężenia, otrzymamy następujący wynik.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

W tym konkretnym przypadku nasze wyniki są takie same jak w przypadku sprzężenia wewnętrznego.

Jeśli jednak zmienimy kolejność tabel w naszym FROM klauzula, otrzymamy podobny wynik do prawego sprzężenia w poprzednim przykładzie.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Możesz więc zobaczyć, że każda wynikowa różnica między lewym i prawym złączeniem zależy wyłącznie od tego, jak uporządkujesz kolumny w FROM klauzula.

Zobacz SQL Left Join, aby uzyskać więcej przykładów, w tym lewe sprzężenie, które łączy 3 tabele.

Pełne połączenie

SQL FULL JOIN (lub FULL OUTER JOIN ) zwraca wszystkie wiersze, o ile w jednej z tabel znajdują się pasujące dane.

Innymi słowy, to tak, jakby w jednym sprzężeniu znajdowało się zarówno lewe, jak i prawe sprzężenie.

Oto przykład pełnego dołączenia.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Zwraca to ten sam wynik, który otrzymaliśmy przy prawym sprzężeniu, ale zwróciłby inny wynik, gdyby w lewej tabeli był wiersz, który nie ma odpowiadającej wartości w prawej tabeli.

Zamieńmy nazwy tabel i uruchommy ponownie.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Tweet     | Bird      |
| Fluffy    | Cat       |
| Scratch   | Cat       |
| Meow      | Cat       |
| Fetch     | Dog       |
| Wag       | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| NULL      | Rabbit    |
+-----------+-----------+
(9 rows affected)

Ten sam wynik.

Zobacz SQL Full Join, aby uzyskać więcej przykładów, w tym pełne złączenie, które łączy 3 tabele.

Łączenie krzyża

SQL CROSS JOIN zwraca wiersze, które łączą każdy wiersz z pierwszej tabeli z każdym wierszem z drugiej tabeli.

Innymi słowy, zwraca iloczyn kartezjański wierszy z tabel w łączeniu.

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Bird      |
| Fetch     | Bird      |
| Scratch   | Bird      |
| Wag       | Bird      |
| Tweet     | Bird      |
| Fluffy    | Bird      |
| Bark      | Bird      |
| Meow      | Bird      |
| Fluffy    | Cat       |
| Fetch     | Cat       |
| Scratch   | Cat       |
| Wag       | Cat       |
| Tweet     | Cat       |
| Fluffy    | Cat       |
| Bark      | Cat       |
| Meow      | Cat       |
| Fluffy    | Dog       |
| Fetch     | Dog       |
| Scratch   | Dog       |
| Wag       | Dog       |
| Tweet     | Dog       |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Dog       |
| Fluffy    | Rabbit    |
| Fetch     | Rabbit    |
| Scratch   | Rabbit    |
| Wag       | Rabbit    |
| Tweet     | Rabbit    |
| Fluffy    | Rabbit    |
| Bark      | Rabbit    |
| Meow      | Rabbit    |
+-----------+-----------+
(32 rows affected)

Jak prawdopodobnie możesz sobie wyobrazić, może to być bardzo niebezpieczne, jeśli użyjesz go na niewłaściwych stołach.

To tak samo, jak zrobienie tego:

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

Możesz dodać WHERE klauzula sprzężenia krzyżowego, która zmieni je w sprzężenie wewnętrzne.

Tak:

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

Wynik:

+-----------+-----------+
| PetName   | PetType   |
|-----------+-----------|
| Fluffy    | Cat       |
| Fetch     | Dog       |
| Scratch   | Cat       |
| Wag       | Dog       |
| Tweet     | Bird      |
| Fluffy    | Dog       |
| Bark      | Dog       |
| Meow      | Cat       |
+-----------+-----------+
(8 rows affected)

Zobacz SQL Cross Join, aby uzyskać więcej przykładów.

Naturalne połączenie

SQL NATURAL JOIN jest typem sprzężenia ekwiwalentnego, w którym predykat łączenia powstaje niejawnie przez porównanie wszystkich kolumn w obu tabelach, które mają te same nazwy kolumn w połączonych tabelach.

Zestaw wyników zawiera tylko jedną kolumnę dla każdej pary kolumn o tej samej nazwie. Jeśli nie zostaną znalezione żadne kolumny o tych samych nazwach, wynikiem będzie sprzężenie krzyżowe.

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

Wynik:

petname | pettype 
---------+---------
 Fluffy  | Cat
 Fetch   | Dog
 Scratch | Cat
 Wag     | Dog
 Tweet   | Bird
 Fluffy  | Dog
 Bark    | Dog
 Meow    | Cat
(8 rows)

W rzeczywistości sprzężenie naturalne nie jest w rzeczywistości typem sprzężenia, zgodnie ze standardem ANSI. Jest to słowo kluczowe, które możesz opcjonalnie wstawić, aby połączenie było połączeniem naturalnym.

Dlatego możemy zmienić powyższy przykład na NATURAL INNER JOIN gdybyśmy chcieli:

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

Jak wspomniano wcześniej, złączenia wewnętrzne są domyślnym typem złączenia, więc jeśli pominiesz typ złączenia (np. INNER , LEFT , RIGHT itp.), to jest traktowane jako sprzężenie wewnętrzne.

Jeśli formatowanie tych wyników wygląda inaczej niż poprzednie, to dlatego, że musiałem przeskoczyć do PostgreSQL, aby uruchomić to zapytanie. Poprzednie przykłady uruchomiłem w SQL Server, ale SQL Server nie obsługuje łączenia naturalnego.

Zobacz SQL Natural Join, aby uzyskać więcej przykładów, w tym naturalne połączenie, które łączy 3 tabele.

Samoprzyłączanie

SQL SELF JOIN dołącza do siebie stół.

Klasycznym przykładem samodzielnego sprzężenia jest tabela Pracownicy. W takiej tabeli jeden pracownik może podlegać innemu pracownikowi. Dlatego możesz użyć samodzielnego łączenia, aby dołączyć do tabeli w kolumnie Identyfikator pracownika i Identyfikator menedżera.

Załóżmy, że mamy następującą tabelę:

+--------------+-------------+------------+-------------+
| EmployeeId   | FirstName   | LastName   | ReportsTo   |
|--------------+-------------+------------+-------------|
| 1            | Homer       | Connery    | NULL        |
| 2            | Bart        | Pitt       | 1           |
| 3            | Maggie      | Griffin    | 1           |
| 4            | Peter       | Farnsworth | 2           |
| 5            | Marge       | Morrison   | NULL        |
| 6            | Lisa        | Batch      | 5           |
| 7            | Dave        | Zuckerberg | 6           |
| 8            | Vlad        | Cook       | 7           |
+--------------+-------------+------------+-------------+

Możemy wykonać samodzielne dołączenie na tym stole, aby zwrócić wszystkich pracowników i ich menedżerów.

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;

Wynik:

+------------------+-----------------+
| Employee         | Manager         |
|------------------+-----------------|
| Homer Connery    |                 |
| Bart Pitt        | Homer Connery   |
| Maggie Griffin   | Homer Connery   |
| Peter Farnsworth | Bart Pitt       |
| Marge Morrison   |                 |
| Lisa Batch       | Marge Morrison  |
| Dave Zuckerberg  | Lisa Batch      |
| Vlad Cook        | Dave Zuckerberg |
+------------------+-----------------+

Zobacz SQL Self Join, aby uzyskać więcej przykładów.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak znaleźć zduplikowane wartości w tabeli SQL?

  2. Jak pracować z dziedziczeniem w Entity Framework Core

  3. Uruchamianie zadań konserwacji bazy danych SQL przy użyciu SQLCMD

  4. Jak skopiować dane z jednej tabeli do drugiej w SQL?

  5. SQL CREATE TABLE dla początkujących