Voir le flux RSS

Blog de Lyche

Les jointures en SQL

Note : 4 votes pour une moyenne de 5,00.
par , 28/09/2016 à 00h10 (1620 Affichages)
Présentation

Une base de données relationnelle, c’est la mise en place d’une organisation claire et efficace des données d’une entreprise basée sur la théorie des ensembles.
Chaque élément constitutif d’un modèle possède un ou plusieurs liens avec un ou plusieurs autres objets. Ce lien est traduit en modélisation par l’exportation d’un élément « la clé » d’une table vers une autre table à laquelle elle est liée. Ceci est vu par la modélisation UML/MERISE. Nous allons parler ici de l’application technique de ces liens par le SQL. À savoir, les jointures.

Dans cet article, nous allons travailler les jointures sur le côté « naturel » des relations via l’utilisation de clé primaires et de clé secondaires. Il est tout à fait possible de joindre 2 tables par des colonnes qui ne sont pas nécessairement la clé primaire. Cela arrive beaucoup lors d’utilisation d’ETL afin de vérifier si une donnée existe ou non dans une table, mais ceci est un autre sujet que nous n’aborderons pas aujourd’hui.

Modélisation

Beaucoup de sites et tutoriaux abordent le sujet de la modélisation (Notamment l’excellent blog de SQLPro aussi, je ne m’y attarderais pas. Non pas que je ne souhaite pas le faire, mais je pense sincèrement que s’attarder sur ce point n’a plus d’intérêt tant le sujet a été débattu et traité par des confrères et que je n’ai rien à apporter à ce qui a déjà été dit pour le moment.

Les Jointures

Ce que l’on nomme « jointure », mot un peu étrange mais parfaitement représentatif de ce qu’il se passe derrière la ligne de code que vous tapez.
Concrètement, la jointure est-ce qui permet au SGBD de faire le lien entre les données des tables que vous voulez exploiter.
Pour nous aider à nous représenter ce « lien », nous allons générer un modèle, simple pour commencer, que nous étofferons au fur et à mesure de notre étude.

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
CREATE DATABASE JointuresSQL;
GO
 
CREATE TABLE dbo.T_SERVICES
( SER_ID         INT IDENTITY(1, 1)
, SER_NOM         VARCHAR(  50 )
, PRIMARY KEY (SER_ID )
);
GO
 
CREATE TABLE dbo.T_PERSONNEL
( PER_ID     INT IDENTITY( 1, 1)
, PER_NOM    VARCHAR( 80 )
, PER_PRENOM VARCHAR( 80 )
, PER_SER_ID INT
PRIMARY KEY (PER_ID),
FOREIGN KEY (PER_SER_ID) REFERENCES dbo.SERVICES( SER_ID )
);
GO
 
INSERT INTO dbo.SERVICES( SER_NOM ) VALUES( 'Direction' );
INSERT INTO dbo.SERVICES( SER_NOM ) VALUES( 'Service Comptable' );
INSERT INTO dbo.SERVICES( SER_NOM ) VALUES( 'Pôle BI' );
INSERT INTO dbo.SERVICES( SER_NOM ) VALUES( 'Pôle CRM' );
INSERT INTO dbo.SERVICES( SER_NOM ) VALUES( 'Pôle Data Quality' );
 
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'BERNARD'    , 'Jacques'    , 1 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DUPONT'     , 'Mathilda'   , 2 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'ROMERO'     , 'George'     , 2 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'CALBERA'    , 'Deborah'    , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'TONETTY'    , 'Aldo'       , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'ALDERAN'    , 'Célyna'     , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'ZATAN'      , 'Zlatan'     , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DUMONT'     , 'François'   , 5 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'LEPRÉ'      , 'Jean'       , 5 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'JENLAIN'    , 'Jean-Michel', 5 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DELCROIX'   , 'Florent'    , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DELVALLÉE'  , 'Amandine'   , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'LEGRAND'    , 'Nicolas'    , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'LEBON'      , 'Francis'    , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DUPONT'     , 'LAURA'      , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DELARUE'    , 'DELPHINE'   , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DELABELIERE', 'ROBIN'      , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'SOUSLARUE'  , 'YANN'       , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'ROSAY'      , 'ANTHONY'    , 5 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'DECAUX'     , 'MATHIEU'    , 5 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'BENALAI'    , 'CORINNE'    , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'SURBLE'     , 'ROSE'       , 4 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'SARGI'      , 'SEBASTIEN'  , 3 );
INSERT INTO dbo.T_PERSONNEL ( PER_NOM, PER_PRENOM, PER_SER_ID ) VALUES( 'BENISEAU'   , 'MATHIS'     , 3 );

Nous allons représenter les différents services d’une entreprise ainsi que les personnes qui la composent. Ce lien est physiquement représenté par la présence du champ PER_SER_ID dans la table T_PERSONNEL.

Ce champ doit nous servir pour ressortir les différentes informations recherches.

Ex : nous souhaitons récupérer la liste du personnel du Pôle CRM.

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
SELECT P.PER_NOM   
     , P.PER_PRENOM
  FROM T_PERSONNEL P
       INNER JOIN T_SERVICES S ON P.PER_SER_ID = T.SER_ID
 WHERE S.SER_NOM = 'Pôle CRM';

La requête, simple, nous permet de joindre les lignes de la table PERSONNEL aux lignes de la table SERVICES par l’identifiant commun qu’il y a dans les 2. Ainsi, le code nous ressortira l’ensemble des données contenues dans la table PERSONNEL faisant partie du département « Pôle CRM »

Nom : Résultat Inner join.jpg
Affichages : 650
Taille : 26,8 Ko

Ceci est la relation la plus simple que l’on puisse avoir entre deux tables. Une relation (1,n) traduite par une jointure interne et qui ne ressortira que les informations dont la condition est vraie dans les 2 sens. (Dans notre cas, l’identifiant 4 pour le pôle CRM)

Les types de jointures

Comme vous avez pu le constater lors de vos études en modélisation, il n’existe pas qu’un seul type de relations entre les éléments d’une base. Voici les différents types de jointures que vous pourrez retrouver ainsi que quelques subtilités qui les caractérisent.

INNER JOIN

Vu plus au-dessus, elle permet de ressortir les lignes quand les conditions sont remplies dans les 2 tables liées par la jointure. C’est la plus simple des jointures.

Le schéma ci-dessous représente le résultat d’une requête INNER JOIN. Seule la partie commune aux deux tables est extraite.

Nom : Effet INNER JOIN.jpg
Affichages : 663
Taille : 19,0 Ko

Schéma INNER JOIN

CROSS JOIN

Une jointure « croisée », c’est ce qu’on appelle un produit cartésien. Le SGBD va croiser chaque ligne de la première table, avec chaque ligne de la deuxième table.
Ex :
Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
SELECT *
  FROM T_PERSONNEL
       CROSS JOIN T_SERVICES

Nom : Résultat cross join.jpg
Affichages : 660
Taille : 132,9 Ko

Que constatez-vous ?

  • Que chaque élément de la table T_SERVICES se retrouve « accolé » à chaque élément de la table T_PERSONNEL.


Pour faciliter la « lecture » vous pouvez rajouter un filtre sur un service, vous verrez alors votre jeu de données limiter à x*1 (X étant le nombre d’éléments de la table T_PERSONNEL)
Le CROSS JOIN peut s’avérer « dangereux », si vous faites le produit cartésien d’une table contenant de gros volumes de données (plusieurs millions de lignes) sur une autre table, vous pouvez vous retrouver avec un nombre de lignes généré parfois hors norme. (1 Million * 1 Million = 1 000 000 000 000) Ça laisse songeur !!

LEFT [OUTER] JOIN

Le schéma ci-dessous représente le résultat d’une requête LEFT JOIN. Toutes les données de la table de gauche ressortiront. En « bonus » les informations communes de la table de droite apparaitront aussi.

Nom : Effet LEFT JOIN.jpg
Affichages : 649
Taille : 18,8 Ko
Schéma LEFT JOIN

La jointure Externe gauche permet d’obtenir un résultat sur des lignes mêmes si elles ne sont pas présentes dans les 2 tables. Le choix du terme LEFT est assez simple, mettez votre requête sur une seule ligne (c’est moche, mais facile à comprendre ainsi !) et bien, la table à gauche des mot clés « LEFT JOIN » (la jointure) et qui est appelée dans les éléments de jointures sera la table « maitresse » de la requête.
OUTER étant optionnel, je le place entre []

  • Tous les éléments non filtrés de la table apparaitront, et ce, même s’il n’y a pas de liens dans la deuxième table.


Pour notre exemple, nous allons rajouter un service dans la table T_SERVICES et tester la jointure.
Vous pourrez constater (et voir la différence en exécutant la précédente requête en INNER JOIN)

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
INSERT INTO dbo.T_SERVICES( SER_NOM ) VALUES ( 'Service Commercial' );
GO
 
 
SELECT *
  FROM dbo.T_SERVICES S
       LEFT JOIN dbo.T_PERSONNEL P ON P.PER_SER_ID = S.SER_ID

Nom : Résultat LEFT JOIN.jpg
Affichages : 633
Taille : 29,5 Ko

Ici, nous pouvons constater que le Service Commercial n’a pas de personnes qui lui sont affectées, et que donc, le SGBD ressort 1 ligne, avec les éléments de la table T_PERSONNEL à NULL.

RIGHT [OUTER] JOIN

Le Schéma ci-dessous représente le résultat d’une requête RIGHT JOIN. Toutes les données de la table de droite ressortiront. En « bonus » les informations communes de la table de droite apparaitront aussi.

Nom : Effet RIGHT JOIN.jpg
Affichages : 678
Taille : 18,4 Ko
Schéma RIGHT JOIN

La jointure externe droite est, intrinsèquement, la même chose que la jointure gauche, avec la seule différence que la table « maitresse » se situe à droite de la commande RIGHT JOIN
Essayez d’exécuter la requête en ne changeant que LEFT par RIGHT. Vous pourrez constater un petit changement dans le résultat !

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
SELECT *
  FROM dbo.T_SERVICES S
       RIGHT JOIN dbo.T_PERSONNE L P ON P.PER_SER_ID = S.SER_ID

  1. la ligne 25, représentant une donnée non-existante dans la table T_PERSONNEL ne s’affiche plus. En effet, la table maitresse étant celle ou les données sont manquantes, la ligne ne peut apparaitre.
  2. L’ordre des données a changé. Dans la première requête, l’ordre est basé sur les données d’insertion de la table T_SERVICES. Ici, sur les données d’insertion de la table T_PERSONNEL.


Nom : Résultat RIGHT JOIN.jpg
Affichages : 614
Taille : 22,3 Ko

FULL JOIN

Le Schéma ci-dessous représente le résultat d’une requête FULL JOIN. L’ensemble des données de deux tables sera sélectionné dans le résultat de la requête. Les parties non communes seront marquées d’un NULL pour tous les champs sans correspondances.

Nom : Résultat FULL JOIN.jpg
Affichages : 664
Taille : 18,1 Ko
Schéma FULL JOIN

Le FULL JOIN est une jointure peu utilisée, car parfois très consommatrice en performances. Un FULL JOIN porte littéralement son nom, il va faire une jointure totale entre les 2 tables et fournir un jeu de données à partir du moment où une ligne est présente dans l’une des deux tables.
C’est comme si vous faisiez un RIGHT et un LEFT JOIN en même temps. Les Colonnes sans correspondance d’une table apparaitront à NULL. Vous l’aurez compris, si votre modèle de données est normé, vous ne devriez pas avoir de cas de données orphelines dans les 2 tables. La table fille ne peut avoir de référence NULL.

SELF JOIN ou AUTO-JOINTURE

Il est à noter que « SELF » n’est pas à proprement parler un mot-clé, il s’agit plutôt d’une information nous indiquant qu’une table s’auto-référence.
Ce cas est le moyen le plus simple de calculer une hiérarchie. Il s’agit, pour une table utilisée dans une jointure, d’être jointe à elle-même. Comme la théorie pour ce genre de cas peut être particulièrement abstraite et peut paraitre illogique, nous allons adapter notre modèle de données, pour lui faire correspondre à notre besoin.

  • Ajoutons un élément permettant de gérer la hiérarchie. (a. De façon logique, une hiérarchie est un lien entre 2 éléments d’une table.)

Ex : BERNARD Jacques, est dans notre modèle à la direction. Comme il est seul, nous supposons qu’il est le Directeur de l’entreprise.
Nous allons choisir 1 personne dans chaque service, elle va devenir arbitrairement « chef du service » et nous allons leur assigner, BERNARD Jacques comme chef. Puis, nous mettrons les personnes de chaque service sous la responsabilité du chef de service.

Comment cela va se traduire ?

  • Par l’ajout d’une colonne « RESP_ID » dans la table du personnel.
  • Par la création d’un lien entre responsable et collaborateur


Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
USE JointuresSQL;
GO
 
ALTER TABLE dbo.T_PERSONNEL ADD PER_RESP_ID INT NULL;
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 1
 WHERE PER_NOM    = 'DUPONT'
   AND PER_PRENOM = 'Mathilda';
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 1
 WHERE PER_NOM    = 'CALBERA'
   AND PER_PRENOM = 'Deborah';
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 1
 WHERE PER_NOM    = 'TONETTY'
   AND PER_PRENOM = 'Aldo';
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 1
 WHERE PER_NOM    = 'TONETTY'
   AND PER_PRENOM = 'Aldo';
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 1
 WHERE PER_NOM    = 'DUMONT'
   AND PER_PRENOM = 'François';	
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 2
 WHERE PER_SER_ID = 2
   AND PER_ID != 2;
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 5
 WHERE PER_SER_ID = 3
   AND PER_ID != 5;
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 4
 WHERE PER_SER_ID = 4
   AND PER_ID != 4;
 
UPDATE dbo.T_PERSONNEL
   SET PER_RESP_ID = 8
 WHERE PER_SER_ID = 5
   AND PER_ID != 8;

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
SELECT PER.PER_SER_ID AS ID_SERVICE
     , RES.PER_NOM    AS RESP_NOM
     , RES.PER_PRENOM AS RESP_PRENOM
     , PER.PER_NOM    AS PER_NOM
     , PER.PER_PRENOM AS PER_PRENOM
  FROM dbo.T_PERSONNEL AS PER
       RIGHT JOIN dbo.T_PERSONNEL AS RES ON PER.PER_RESP_ID = RES.PER_ID
 WHERE PER.PER_NOM IS NOT NULL
 ORDER BY PER.PER_SER_ID, RES.PER_NOM, RES.PER_PRENOM
;

Vous pourrez constater qu’il va manquer quelques précisions dans le classement des personnes (à savoir qui est le directeur de l’entreprise et qu'il devrait se situer en haut).
Il est à noter que les normes SQL ont énormément évolué et que des méthodes ont été mises en place pour permettre de gérer au mieux une hiérarchie. (Voir Mon cours sur les CTE et requêtes récursives). Nous n’aborderons pas le sujet ici, car il nécessite une assez bonne connaissance de SQL pour l’appréhender.

NATURAL JOIN

Le NATURAL JOIN est une norme permettant la « simplification » de l’écriture de requêtes. Elle utilise l’intelligence du moteur de données, à partir du moment où on lui mâche un peu le travail, en nommant les FK des tables filles comme le nom de la colonne d’origine.
Dans notre cas, il nous faudrait remplacer le nom de la colonne T_PERSONNEL.PER_SER_ID en T_PERSONNEL.SER_ID
Et la requête s’écrirait ainsi

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
SELECT *
  FROM T_PERSONNEL
       NATURAL JOIN T_SERVICES

C’est immédiatement plus lisible, mais aussi plus « gourmand » et demande au SGBD un peu plus d’efforts pour appliquer les jointures et calculer son plan d’exécution.
Personnellement, je ne m’en sers jamais. Simplement parce que toutes les autres jointures comportent la clause ON qui permettent de voir en un coup d’œil quelles sont les colonnes de jointures entre les tables et qu’avoir des écritures différentes dans une même requête peut brouiller la lecture. De plus, les performances de vos requêtes se trouvent affectées par le fait que le SGBD doit fournir un effort supplémentaire d’identification des liaisons entre tables. Sur de petites volumétries, cela ne gêne pas, mais il ne faut jamais oublier qu’une base de données est destinée à vivre longtemps, et qu’à forte volumétrie comme sur lesquelles j’ai pu travailler (entre 1 et 5 milliards de lignes), cela s’avère être source de ralentissement.


CAS PARTICULIERS :

EXISTS

EXISTS n’est pas, à proprement parler une jointure. En effet, sa forme première d’utilisation est de déclencher ou non une requête si une donnée existe en tant que résultat d’une sous-requête. C’est-à-dire qu’à partir du moment, où il y aura au moins 1 ligne retournée dans la sous-requête, alors l’ensemble de la requête sera exécuté, sinon, il ne se passera rien. (C’est une sorte de « IF » plus « classe »)

Mais il existe une autre forme de « EXISTS ». Elle consiste à lier le résultat de la sous-requête aux lignes de la requête principale. Le principe d’une jointure étant de relier les tables par une égalité sur un à n champs.

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
-- Forme première du EXISTS
SELECT *
  FROM T_SERVICES
 WHERE EXISTS ( SELECT 1
                  FROM T_PERSONNEL );
 
-- 2ème forme du EXISTS
SELECT *
  FROM T_SERVICES
 WHERE EXISTS ( SELECT 1
                  FROM T_PERSONNEL
                 WHERE T_SERVICES.SER_ID = T_PERSONNEL.PER_SER_ID );

On peut constater que la première version n’applique pas de filtre. Si l’on remplace le « EXISTS » par un « NOT EXISTS », il n’y aura plus de données du tout. La requête principale ne ressortira pas de données, car il y a des données alors que nous n’en voulons pas.
La deuxième forme de EXISTS, va reproduire pratiquement le même effet qu’un INNER JOIN et permettra de lister les services dans lesquels il y a au moins une personne.
Le gros avantage, et c’est pour cette raison que je place la clause EXISTS dans les « pseudo jointures » c’est qu’on peut reproduire l’effet d’un INNER JOIN, sans avoir les contraintes de doublons générés par une relation 1,n. Mais il devient impossible de remonter les données de la table dans le EXISTS sous la forme de colonnes.
N.B : Vous aurez probablement constaté le « SELECT 1 » de la sous requête. Il est important de savoir et comprendre que l’important c’est pas le résultat du SELECT, mais, dans la première forme qu’il y ait une valeur quelle qu’elle soit, et dans la 2ème forme, que l’égalité existe ou non. Le SELECT dans la 2ème forme n’est même pas lu par la requête principale.

FILTRES ET PRE FILTRES

La plupart des personnes pratiquantes du SQL savent faire des requêtes avec des jointures simples et des filtres. Moins nombreux sont ceux qui savent faire la différence entre un filtre (clause WHERE) et un préfiltre.
Un filtre, ça sert à limiter le nombre de lignes que l’on souhaite faire apparaitre en résultat d’un select. C’est ce qu’on appelle communément les règles de gestion (RG). Mais, il est possible, lorsque l’on travaille avec du LEFT/RIGHT JOIN d’appliquer un premier filtre à une table afin de ne pas nous perturber avec des données qui ne nous intéressent pas en provenance d’une table jointe.
Exemple :
Je souhaite connaitre les personnes de la direction. Un filtre normal s’applique et nous aurons 1 ligne.

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
-- 1 - Filtre sur les personnes du service Direction
 
SELECT *
  FROM dbo.T_PERSONNEL P
       LEFT JOIN dbo.T_SERVICES S ON P.PER_SER_ID = S.SER_ID
 WHERE S.SER_ID = 1;

Nom : Résultat Filtre Direction.jpg
Affichages : 587
Taille : 18,0 Ko

Comme attendu, notre filtre nous remonte l’ensemble des lignes dont les personnes sont affiliées au service « Direction ».
Cependant, il est parfois nécessaire de conserver l’ensemble des données d’une table, mais de n’afficher que certaines données, et ce, pour mettre en exergue certains faits.
Dans la requête suivante, on pourrait croire que cette personne est seule dans son entreprise, hors, il n’en est rien. Appliquons le même filtre, mais en « préfiltre ».

Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
--2 - Pré-Filtre sur le service Direction
SELECT *
  FROM dbo.T_PERSONNEL P
       LEFT JOIN dbo.T_SERVICES S ON P.PER_SER_ID = S.SER_ID
                                 AND S.SER_ID = 1;

Nom : Résultat Pré-Filtre Direction.jpg
Affichages : 658
Taille : 40,0 Ko

Vous pouvez constater que la requête ne remonte les informations de la table T_SERVICES que pour la direction, mais que les autres personnes sont quand même présentes dans le résultat.
Il devient, ainsi, facile d’identifier telle ou telle personne dans une liste de nombreuses autres.
Ce cas est plus courant qu’on ne le croit et bons nombres de résultats attendus peuvent se trouver faux à la suite d’une mauvaise application de RG entre le filtre et le pré filtre.

Conclusion :

Les normes SQL prévoient bon nombre de cas de lecture de données entre les tables. Les différentes jointures que nous avons étudiées dans ce document prennent en compte les différentes possibilités de liaisons de vos tables lorsque vous réalisez votre modèle. Si vous désirez progresser dans votre qualité de code SQL, il vous sera impératif de parfaitement maîtriser les jointures, qui en sont la base.

Remerciements
Je remercie Sylvain Del TATTO (minot83), Jean-Marie BAGNIS(jimbolion), Célia POTOT (Erielle) ainsi Frédérique Brossard (Directeur Adjoint au pôle BI chez MCNext) et Séverine CAPON (GeekMokona) pour leur relecture, conseil et correction qui m’ont permis de publier cet article.

Envoyer le billet « Les jointures en SQL » dans le blog Viadeo Envoyer le billet « Les jointures en SQL » dans le blog Twitter Envoyer le billet « Les jointures en SQL » dans le blog Google Envoyer le billet « Les jointures en SQL » dans le blog Facebook Envoyer le billet « Les jointures en SQL » dans le blog Digg Envoyer le billet « Les jointures en SQL » dans le blog Delicious Envoyer le billet « Les jointures en SQL » dans le blog MySpace Envoyer le billet « Les jointures en SQL » dans le blog Yahoo

Mis à jour 28/09/2016 à 00h32 par Lyche

Catégories
Sans catégorie

Commentaires