sql >> Databáze >  >> RDS >> Database

Výukový program připojení SQL

SQL spojení je místo, kde spustíte dotaz, který spojuje více tabulek.

Tento výukový program spojení SQL představuje základní příklady spojení SQL a také úvod do různých typů spojení.

Typy spojení SQL

Standard ANSI SQL specifikuje pět typů spojení, jak je uvedeno v následující tabulce.

Typ připojení Popis

INNER JOIN
Vrátí řádky, pokud je v obou tabulkách alespoň jeden řádek, který odpovídá podmínce spojení.

LEFT OUTER JOIN
nebo
LEFT JOIN
Vrátí řádky, které obsahují data v levé tabulce (vlevo od JOIN klíčové slovo), i když v pravé tabulce nejsou žádné odpovídající řádky.

RIGHT OUTER JOIN
nebo
RIGHT JOIN
Vrátí řádky, které obsahují data v pravé tabulce (vpravo od JOIN klíčové slovo), i když v levé tabulce nejsou žádné odpovídající řádky.

FULL OUTER JOIN
nebo
FULL JOIN
Vrátí všechny řádky, pokud jsou v jedné z tabulek odpovídající údaje.
CROSS JOIN Vrátí řádky, které kombinují každý řádek z první tabulky s každým řádkem z druhé tabulky.

Existují také další termíny pro různé operace spojení, například následující:

Připojit se Popis
Vlastní připojení Když se tabulka připojí sama k sobě.
Přirozené připojení Implicitní spojení založené na společných sloupcích ve dvou spojovaných tabulkách.
Equi-join Spojení obsahující pouze porovnání rovnosti v predikátu spojení.

Syntaxe spojení SQL

Vnitřní spojení lze zadat buď v FROM nebo WHERE doložky. Vnější spojení a křížová spojení lze zadat v FROM pouze doložka.

Chcete-li vytvořit spojení SQL v FROM klauzule, udělejte něco takového:

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

Kde JoinType určuje, jaký druh spojení se provádí, a JoinCondition definuje predikát, který má být vyhodnocen pro každý pár spojených řádků.

Chcete-li zadat spojení v WHERE klauzule, udělejte něco takového:

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

Opět JoinCondition definuje predikát, který má být vyhodnocen pro každý pár spojených řádků.

Také vše uzavřeno v hranatých závorkách ([] ) je volitelný.

Ukázkové tabulky pro příklady v tomto kurzu

Většina příkladů v tomto tutoriálu provádí spojení s následujícími dvěma tabulkami.

PetTypes tabulka:

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

Pets tabulka:

+---------+-------------+-----------+-----------+------------+
| 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)

Vnitřní spojení

SQL INNER JOIN vrátí řádky, pokud je v obou tabulkách alespoň jeden řádek, který odpovídá podmínce spojení.

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

Výsledek:

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

Chcete-li určit vnitřní spojení v FROM klauzule, používáme INNER JOIN . Používáme také ON klíčové slovo pro definování predikátu, který má být vyhodnocen pro každý pár spojených řádků.

Bez ohledu na typ spojení kvalifikujeme naše názvy sloupců názvy tabulek. Důvodem, proč to děláme, je vyhnout se jakékoli nejednoznačnosti ohledně názvů sloupců mezi tabulkami. Obě tabulky mohou mít sloupce se stejným názvem (jako v našem příkladu) a v takových případech DBMS nebude vědět, na který sloupec odkazujete. Přidání názvů sloupců před názvy jejich tabulek zajistí, že odkazujete na správný sloupec, a zabráníte jakýmkoli chybám, které by mohly vzniknout v důsledku nejasností ohledně toho, na který sloupec odkazujete.

V tomto příkladu mají obě tabulky PetTypeId sloupec. Pets.PetTypeId sloupec je cizí klíč k PetTypes.PetTypeId sloupec, což je primární klíč pro tuto tabulku.

V tomto příkladu vidíme, že jsou vrácena všechna domácí zvířata, ale ne všechny typy zvířat jsou vráceny. V Pets nejsou žádní králíci tabulka, a tedy Rabbits pet type není vrácen.

Důvodem jsou Rabbits typ není vrácen, protože INNER JOIN vrátí řádky pouze v případě, že v obou tabulkách existuje alespoň jeden řádek, který odpovídá podmínce spojení. V tomto případě Rabbits je pouze v jedné tabulce (PetTypes tabulka).

Všimněte si, že typ spojení je volitelný. Proto většina (pokud ne všechny) DBMS umožňuje vynechat INNER klíčové slovo. Když toto vynecháte (tj. zadejte pouze JOIN ), předpokládá se, že jde o vnitřní spojení.

Proto bychom mohli výše uvedený příklad přepsat na toto:

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

Stejně jako u jakéhokoli příkazu SQL také FROM klauzule může být na jednom celém řádku, pokud chcete:

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

Aliasy

Při provádění spojení SQL je běžnou praxí používat aliasy tabulek. Aliasy pomáhají, aby byl kód stručnější a snáze čitelný.

Proto bychom mohli předchozí příklad změnit na tento:

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

Výsledek:

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

Equi-Join

Výše uvedené spojení může být také označováno jako equi-join . Rovnocenné spojení je spojení obsahující pouze porovnání rovnosti v predikátu spojení.

Jiný způsob zápisu výše uvedeného spojení je tento:

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

Výsledek:

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

Toto je příklad zadání vnitřního spojení v WHERE doložka. Jednoduše jsme poskytli čárkami oddělený seznam tabulek a poté WHERE stav. Pokud bychom vynechali WHERE stavu, skončili bychom s CROSS JOIN .

Pro mnoho začátečníků je výše uvedená syntaxe mnohem srozumitelnější než INNER JOIN syntax. Pokud chcete, klidně použijte tuto syntaxi, mějte však na paměti, že většina SQL profesionálů dává přednost použití INNER JOIN syntaxe z předchozího příkladu.

Další příklady, včetně vnitřního spojení, které spojuje 3 tabulky, najdete v tématu SQL Inner Join.

Správné spojení

Také známý jako RIGHT OUTER JOIN , RIGHT JOIN vrátí řádky, které mají data v pravé tabulce (vpravo od JOIN klíčové slovo), i když v levé tabulce nejsou žádné odpovídající řádky.

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

Výsledek:

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

V tomto případě máme navíc PetType hodnota – Rabbit – i když v Pets není žádné zvíře stůl tohoto typu. Výsledkem je NULL hodnotu v PetName sloupec proti Rabbit .

Další příklady, včetně pravého spojení, které spojuje 3 tabulky, najdete v tématu SQL Right Join.

Levé spojení

Také známý jako LEFT OUTER JOIN , SQL LEFT JOIN vrátí řádky, které obsahují data v levé tabulce (vlevo od JOIN klíčové slovo), i když v pravé tabulce nejsou žádné odpovídající řádky.

Toto je opak RIGHT JOIN .

Pokud změníme předchozí příklad tak, aby používal levé spojení, dostaneme následující výsledek.

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

Výsledek:

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

V tomto konkrétním případě jsou naše výsledky stejné jako u vnitřního spojení.

Pokud však zaměníme pořadí tabulky v našem FROM klauzule, dostaneme podobný výsledek jako správné spojení v předchozím příkladu.

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

Výsledek:

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

Můžete tedy vidět, že jakýkoli výsledný rozdíl mezi levým a pravým spojením závisí pouze na tom, jak objednáváte sloupce v FROM doložka.

Další příklady, včetně levého spojení, které spojuje 3 tabulky, najdete v tématu SQL Left Join.

Úplné připojení

SQL FULL JOIN (nebo FULL OUTER JOIN ) vrátí všechny řádky, pokud jsou v jedné z tabulek odpovídající údaje.

Jinými slovy, je to jako mít v jednom spojení levé i pravé spojení.

Zde je příklad úplného připojení.

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

Výsledek:

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

Vrátí to stejný výsledek, jaký jsme dostali se správným spojením, ale pokud by v levé tabulce byl řádek, který by v pravé tabulce neměl odpovídající hodnotu, vrátilo by to jiný výsledek.

Zaměňme názvy tabulek a spusťte to znovu.

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

Výsledek:

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

Stejný výsledek.

Další příklady, včetně úplného spojení, které spojuje 3 tabulky, najdete v tématu SQL Full Join.

The Cross Join

SQL CROSS JOIN vrátí řádky, které kombinují každý řádek z první tabulky s každým řádkem z druhé tabulky.

Jinými slovy, vrací kartézský součin řádků z tabulek ve spojení.

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

Výsledek:

+-----------+-----------+
| 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 si pravděpodobně dokážete představit, mohlo by to být velmi nebezpečné, pokud jej spustíte proti nesprávným tabulkám.

Je to stejné jako toto:

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

Můžete přidat WHERE klauzule na křížové spojení, které z něj udělá vnitřní spojení.

Takhle:

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

Výsledek:

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

Další příklady viz SQL Cross Join.

Přirozené spojení

SQL NATURAL JOIN je typ ekvi-spojení, kde predikát spojení vzniká implicitně porovnáním všech sloupců v obou tabulkách, které mají stejné názvy sloupců ve spojených tabulkách.

Sada výsledků obsahuje pouze jeden sloupec pro každou dvojici stejně pojmenovaných sloupců. Pokud nebudou nalezeny žádné sloupce se stejnými názvy, výsledkem bude křížové spojení.

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

Výsledek:

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

Ve skutečnosti přirozené spojení není ve skutečnosti typem spojení, jak je zvažováno standardem ANSI. Je to klíčové slovo, které můžete volitelně vložit, aby se spojení stalo přirozeným spojením.

Proto bychom mohli výše uvedený příklad změnit na NATURAL INNER JOIN pokud bychom chtěli:

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

Jak již bylo zmíněno dříve, vnitřní spojení jsou výchozím typem spojení, takže pokud vynecháte typ spojení (např. INNER , LEFT , RIGHT , atd.), pak se s ním zachází jako s vnitřním spojením.

Pokud formátování těchto výsledků vypadá jinak než předchozí výsledky, je to proto, že jsem musel přeskočit na PostgreSQL, abych mohl spustit tento dotaz. Spustil jsem předchozí příklady v SQL Server, ale SQL Server nepodporuje přirozené spojení.

Další příklady, včetně přirozeného spojení, které spojuje 3 tabulky, najdete v tématu SQL Natural Join.

Sebe připojení

SQL SELF JOIN připojuje stůl k sobě.

Klasickým příkladem vlastního připojení je tabulka Zaměstnanci. V takové tabulce se může jeden zaměstnanec hlásit jinému zaměstnanci. Proto můžete použít vlastní spojení ke spojení tabulky ve sloupci ID zaměstnance a ID manažera.

Předpokládejme, že máme následující tabulku:

+--------------+-------------+------------+-------------+
| 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           |
+--------------+-------------+------------+-------------+

Můžeme se sami připojit k tomuto stolu a vrátit všechny zaměstnance a jejich manažery.

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;

Výsledek:

+------------------+-----------------+
| 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 |
+------------------+-----------------+

Další příklady viz SQL Self Join.


  1. Udělení přístupu uživatele msdb k profilu pošty databáze v SQL Server (T-SQL)

  2. Omezení křížové tabulky MS SQL Serveru

  3. Aktualizujte záznamy v tabulce z CTE

  4. Jak navrhnout systém připravený na lokalizaci