Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Jointure de trois tables avec des jointures autres que INNER JOIN

Oui, j'utilise ces trois JOIN, bien que j'ai tendance à m'en tenir à l'utilisation de LEFT (OUTER) JOIN s au lieu de mélanger les jointures LEFT et RIGHT JOIN. J'utilise aussi FULL OUTER JOIN s et CROSS JOIN s.

En résumé, un INNER JOIN limite le jeu de résultats uniquement aux enregistrements remplis par la condition JOIN. Considérez les tableaux suivants

MODIF : J'ai renommé les noms de table et les préfixe avec @ afin que les variables de table puissent être utilisées par toute personne lisant cette réponse et souhaitant expérimenter.

Si vous souhaitez également expérimenter cela dans le navigateur, j'ai tout configuré sur SQL Fiddle aussi ;

@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

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

Une INNER JOIN Instruction SQL, jointe sur le id champ

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

Résultats en

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

Une LEFT JOIN renverra un jeu de résultats avec tous les enregistrements de la table sur le côté gauche de la jointure (si vous deviez écrire l'instruction en une seule ligne, la table qui apparaît en premier) et les champs de la table sur le côté droit de la jointure qui correspondent à l'expression de jointure et sont inclus dans le SELECT clause. Manquant les détails seront remplis avec NULL

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

Résultats en

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

Une RIGHT JOIN est la même logique qu'un LEFT JOIN mais renverra tous les enregistrements du côté droit de la jointure et les champs du côté gauche qui correspondent à l'expression de jointure et sont inclus dans le SELECT clause.

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

Résultats en

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

Bien sûr, il y a aussi le FULL OUTER JOIN , qui inclut les enregistrements des deux tables jointes et renseigne les éléments manquants détails avec NULL.

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

Résultats en

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

Et un CROSS JOIN (également appelé CARTESIAN PRODUCT ), qui est simplement le produit de l'application croisée des champs dans le SELECT déclaration d'une table avec les champs dans le SELECT déclaration de l'autre table. Notez qu'il n'y a pas d'expression de jointure dans un CROSS JOIN

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

Résultats en

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

MODIF :

Imaginez qu'il existe maintenant une Table3

@Table3

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

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

Maintenant, les trois tables sont jointes avec 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

Résultats en

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

Il peut être utile de comprendre ce résultat en pensant que les enregistrements avec id 2 et 3 sont les seuls communs aux 3 tables et sont également le champ sur lequel nous joignons chaque table.

Maintenant tous les trois avec 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

Résultats en

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

La réponse de Joel est une bonne explication pour expliquer cet ensemble de résultats (le tableau 1 est la table de base/d'origine).

Maintenant avec un INNER JOIN et un 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

Résultats en

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

Bien que nous ne connaissions pas l'ordre dans lequel l'optimiseur de requête effectuera les opérations, nous examinerons cette requête de haut en bas pour comprendre le jeu de résultats. Le INNER JOIN sur les identifiants entre Table1 et Table2 limitera le jeu de résultats aux seuls enregistrements satisfaits par la condition de jointure, c'est-à-dire les trois lignes que nous avons vues dans le tout premier exemple. Ce temporaire le jeu de résultats sera alors LEFT JOIN ed à Table3 sur les identifiants entre Table1 et Tables ; Il y a des enregistrements dans Table3 avec id 2 et 3, mais pas id 1, donc le champ t3.name contiendra des détails pour 2 et 3 mais pas 1.