sql >> Databáze >  >> RDS >> Sqlserver

Spojení tří tabulek s jinými spojeními než INNER JOIN

Ano, používám všechny tři tyto JOINy, i když mám tendenci používat pouze LEFT (OUTER) JOIN s místo vzájemného míchání LEFT a RIGHT JOIN. Také používám FULL OUTER JOIN s a CROSS JOIN s.

Stručně řečeno, INNER JOIN omezuje resultset pouze na ty záznamy, které splňují podmínku JOIN. Zvažte následující tabulky

UPRAVIT: Přejmenoval jsem názvy tabulek a předponu jim @ takže proměnné tabulky lze použít pro každého, kdo čte tuto odpověď a chce experimentovat.

Pokud s tím také chcete experimentovat v prohlížeči, Všechno jsem to nastavil na SQL Fiddle také;

@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 kód

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 Příkaz SQL spojený s id pole

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

Výsledky v

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

LEFT JOIN vrátí sadu výsledků se všemi záznamy z tabulky na levé straně spojení (pokud byste příkaz zapsali jako jeden řádek, tabulka, která se zobrazí jako první) a pole z tabulky na pravé straně spojení které odpovídají výrazu spojení a jsou zahrnuty v SELECT doložka. Chybí podrobnosti budou vyplněny hodnotou NULL

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

Výsledky v

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

RIGHT JOIN má stejnou logiku jako LEFT JOIN ale vrátí všechny záznamy z pravé strany spojení a pole z levé strany, která odpovídají výrazu spojení a jsou zahrnuta v SELECT doložka.

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

Výsledky v

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

Samozřejmostí je také FULL OUTER JOIN , která zahrnuje záznamy z obou spojených tabulek a vyplní všechny chybějící podrobnosti s NULL.

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

Výsledky v

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

A CROSS JOIN (známé také jako CARTESIAN PRODUCT ), což je jednoduše produkt křížového použití polí v SELECT příkaz z jedné tabulky s poli v SELECT výpis z druhé tabulky. Všimněte si, že CROSS JOIN neobsahuje žádný spojovací výraz

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

Výsledky v

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

UPRAVIT:

Představte si, že nyní existuje Tabulka 3

@Table3

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

SQL kód

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

Nyní jsou všechny tři stoly spojeny 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

Výsledky v

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

Tomuto výsledku by mohlo pomoci pochopit, že záznamy s ID 2 a 3 jsou jediné společné všem 3 tabulkám a jsou také pole, na kterém se připojujeme ke každému stolu.

Nyní všechny tři s 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

Výsledky v

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

Joelova odpověď je dobrým vysvětlením pro vysvětlení této sady výsledků (Tabulka1 je základní/původní tabulka).

Nyní s INNER JOIN a 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

Výsledky v

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

Přestože neznáme pořadí, ve kterém bude optimalizátor dotazů provádět operace, podíváme se na tento dotaz shora dolů, abychom porozuměli množině výsledků. INNER JOIN on ids mezi Tabulkou1 a Tabulkou2 omezí sadu výsledků pouze na ty záznamy, které splňují podmínku spojení, tj. na tři řádky, které jsme viděli v úplně prvním příkladu. Toto dočasné resultset pak bude LEFT JOIN ed to Table3 na ids mezi Table1 and Tables; V tabulce 3 jsou záznamy s id 2 a 3, ale ne id 1, takže pole t3.name bude obsahovat podrobnosti pro 2 a 3, ale ne 1.



  1. Dynamické vzorkování Killing Me ve 12c

  2. Base64 kódování a dekódování v oracle

  3. Nové změny sloupců pouze metadata v SQL Server 2016

  4. SQL vyberte max(datum) a odpovídající hodnotu