sql >> Database >  >> RDS >> Sqlserver

Three table join met andere joins dan INNER JOIN

Ja, ik gebruik alle drie de JOIN's, hoewel ik de neiging heb om alleen LEFT (OUTER) JOIN te gebruiken s in plaats van LEFT en RIGHT JOINs door elkaar te mengen. Ik gebruik ook FULL OUTER JOIN s en CROSS JOIN v.

Samengevat, een INNER JOIN beperkt de resultatenset alleen tot die records die voldoen aan de JOIN-voorwaarde. Bekijk de volgende tabellen

BEWERKEN: Ik heb de namen van de tabellen hernoemd en ze voorafgegaan door @ zodat tabelvariabelen kunnen worden gebruikt voor iedereen die dit antwoord leest en wil experimenteren.

Als je hiermee ook in de browser wilt experimenteren, Ik heb dit allemaal ingesteld op SQL Fiddle ook;

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

Een INNER JOIN SQL-instructie, samengevoegd op de id veld

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

Resultaten in

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

EEN LEFT JOIN retourneert een resultatenset met alle records uit de tabel aan de linkerkant van de join (als u de verklaring als een one-liner zou uitschrijven, de tabel die als eerste verschijnt) en velden uit de tabel aan de rechterkant van de join die overeenkomen met de join-expressie en zijn opgenomen in de SELECT clausule. Ontbrekend details worden gevuld met NULL

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

Resultaten in

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

EEN RIGHT JOIN is dezelfde logica als een LEFT JOIN maar retourneert alle records van de rechterkant van de join en velden van de linkerkant die overeenkomen met de join-expressie en zijn opgenomen in de SELECT clausule.

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

Resultaten in

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

Natuurlijk is er ook de FULL OUTER JOIN , die records van beide samengevoegde tabellen bevat en alle ontbrekende . vult details met NULL.

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

Resultaten in

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

En een CROSS JOIN (ook bekend als een CARTESIAN PRODUCT ), wat eenvoudigweg het product is van kruislings toepassende velden in de SELECT statement uit één tabel met de velden in de SELECT verklaring van de andere tafel. Merk op dat er geen join-expressie is in een CROSS JOIN

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

Resultaten in

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

BEWERKEN:

Stel je voor dat er nu een Tabel3 is

@Table3

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

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

Nu zijn alle drie de tafels samengevoegd met 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

Resultaten in

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

Het kan helpen om dit resultaat te begrijpen door te denken dat records met id 2 en 3 de enige zijn die alle drie de tabellen en gemeen hebben. zijn ook het veld waarop we aan elke tafel deelnemen.

Nu alle drie met 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

Resultaten 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

Het antwoord van Joel is een goede verklaring voor het verklaren van deze resultatenset (Tabel1 is de basis/oorsprongstabel).

Nu met een INNER JOIN en een 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

Resultaten in

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

Hoewel we niet weten in welke volgorde de query-optimizer de bewerkingen zal uitvoeren, zullen we deze query van boven naar beneden bekijken om de resultatenset te begrijpen. De INNER JOIN op id's tussen Tabel1 en Tabel2 beperkt de resultatenset tot alleen die records die voldoen aan de join-voorwaarde, d.w.z. de drie rijen die we in het allereerste voorbeeld zagen. Deze tijdelijke resultaatset is dan LEFT JOIN ed to Table3 op id's tussen Table1 en Tables; Er zijn records in Tabel 3 met id 2 en 3, maar niet id 1, dus het veld t3.name bevat details voor 2 en 3 maar niet 1.



  1. Hoe associatieve arrays in Oracle Database te maken

  2. LISTAGG() Functie in Oracle

  3. PG::UndefinedTable:ERROR:relatie bestaat niet met een juiste Rails-naamgeving en -conventie

  4. Hoe het verschil van dagen/maanden/jaren (datediff) tussen twee datums te krijgen?