Le guide de survie des jointures : L'art de marier vos données sans créer de paradoxe temporel

Cet article en deux mots :

Ne laissez pas vos données compartimentées provoquer l'apocalypse ! Découvrez comment lier efficacement vos tables avec la PROC SQL, de l'indispensable INNER JOIN à la souplesse du LEFT JOIN, tout en évitant le piège du produit cartésien pour des analyses SAS performantes et structurées.

Skynet a un problème. Dans notre précédent article, nous avons brillamment réussi à lister tous les Terminators actifs. C'est bien. Mais un Terminator sans arme, c'est juste un gros robot de compagnie un peu effrayant.

Le souci, c'est que les données de Cyberdyne Systems sont compartimentées. Les informations des cyborgs sont dans une table, et l'inventaire de l'arsenal est dans une autre. Si nous envoyons un T-800 dans le passé sans savoir quelle arme lui est assignée, on risque fort de créer un paradoxe temporel (ou pire, de rater la cible).

Il est temps d'apprendre à lier nos tables avec la PROC SQL. C'est ce qu'on appelle les jointures (ou Joins).

Mise en place : Nos deux tables

Pour illustrer cela, créons nos deux tables distinctes. Remarquez qu'elles ont une colonne en commun : ID_Arme. C'est notre clé de liaison.

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
/* Table 1 : Nos unités */
data work.cyborgs;
length Modele $10 Statut $15 ID_Arme $5;
infile datalines dlm=',';
input Modele $ Statut $ ID_Arme $;
datalines;
T-800,Actif,W01
T-1000,Actif,W02
T-X,Actif,W03
T-600,En test, /* Le T-600 n'a pas encore d'arme assignée */
;
run;

/* Table 2 : L'arsenal de Skynet */
data work.arsenal;
length ID_Arme $5 Nom_Arme $25 Puissance 8;
infile datalines dlm=',';
input ID_Arme $ Nom_Arme $ Puissance;
datalines;
W01,Fusil à plasma,80
W02,Lames en métal liquide,95
W03,Canon à particules,100
W04,Minigun rotatif,75 /* Cette arme n'est assignée à personne */
;
run;

1. Le Produit Cartésien : L'erreur qui fait planter la Matrice

Avant de bien faire, voyons comment mal faire. Si vous demandez à SAS de lier deux tables sans lui expliquer comment les lier, il va paniquer et associer chaque ligne de la première table avec chaque ligne de la deuxième table.

1
2
3
4
5
/* À NE PAS FAIRE EN PRODUCTION ! */
proc sql;
select Modele, Nom_Arme
from work.cyborgs, work.arsenal;
quit;

Résultat ? 4 cyborgs multipliés par 4 armes = 16 lignes. SAS vous affiche un T-800 armé d'un canon à particules, puis d'un Minigun, puis de lames... Bref, un cauchemar logistique. C'est le produit cartésien. En certification, retenez que c'est ce qui se passe si vous oubliez la clause de jointure.

2. Inner Join : La jointure parfaite

Pour éviter le chaos, nous allons utiliser un INNER JOIN. Cette jointure ne conserve que les lignes qui ont une correspondance dans les deux tables.

Nous allons également utiliser des alias de tables (c pour cyborgs, a pour arsenal) pour ne pas avoir à réécrire le nom complet des tables à chaque fois.

1
2
3
4
5
6
proc sql;
select c.Modele, c.Statut, a.Nom_Arme, a.Puissance
from work.cyborgs as c
inner join work.arsenal as a
on c.ID_Arme = a.ID_Arme; /* Voici la clause magique ! */
quit;

Ici, la clause ON indique à SAS de chercher les ID_Arme identiques. Note importante : Le T-600 (sans arme) et le Minigun (sans porteur) ont disparu du résultat final. L'INNER JOIN est exclusif.

3. Left Join : Ne laisser aucun soldat derrière

Que faire si Skynet veut la liste de tous ses cyborgs, qu'ils soient armés ou non ? C'est là qu'intervient le LEFT JOIN (Jointure externe gauche).

Il prendra toutes les lignes de la table de gauche (Cyborgs), et y collera les informations de la table de droite (Arsenal) si elles existent. Sinon, il mettra des valeurs manquantes.

1
2
3
4
5
6
proc sql;
select c.Modele, c.Statut, a.Nom_Arme
from work.cyborgs as c
left join work.arsenal as a
on c.ID_Arme = a.ID_Arme;
quit;

Cette fois, le T-600 apparaît bien dans la liste, avec un espace vide (valeur manquante) dans la colonne Nom_Arme. Skynet sait maintenant qu'il doit équiper cette unité d'urgence.

4. Right et Full Joins : Pour être exhaustif

La logique s'étend facilement :

  • RIGHT JOIN : Garde toutes les lignes de la table de droite (l'arsenal complet), et affiche les cyborgs associés. S'affichera alors notre Minigun avec un porteur vide.
  • FULL JOIN : Le grand rassemblement. Garde absolument tout (tous les cyborgs ET toutes les armes), en faisant les correspondances là où c'est possible.
1
2
3
4
5
6
7
/* Exemple d'un inventaire total */
proc sql;
select c.Modele, a.Nom_Arme
from work.cyborgs as c
full join work.arsenal as a
on c.ID_Arme = a.ID_Arme;
quit;

Le conseil Certification

Dans vos anciens codes SAS (ou chez certains collègues), vous verrez souvent des jointures écrites avec une clause WHERE au lieu d'un INNER JOIN ... ON.

1
2
3
4
/* Syntaxe SAS traditionnelle (fonctionne comme un Inner Join) */
select c.Modele, a.Nom_Arme
from work.cyborgs as c, work.arsenal as a
where c.ID_Arme = a.ID_Arme;

Bien que cela fonctionne parfaitement pour une jointure stricte, la syntaxe avec JOIN ... ON (norme ANSI) est vivement recommandée. Elle sépare clairement la logique de liaison (ON) des filtres de vos données (WHERE). De plus, pour faire un LEFT JOIN, la syntaxe ANSI est obligatoire !

Conclusion

Vous savez maintenant relier vos tables sans provoquer l'apocalypse. Les jointures sont le cœur de l'analyse relationnelle et vous feront gagner un temps précieux par rapport à la classique combinaison de PROC SORTLa PROC SORT est une procédure SAS permettant de réorganiser les observations d'une table selon l'ordre croissant ou décroissant d'une ou plusieurs variables, tout en supprimant les doublons. et d'étape DATA avec MERGE.

Dans l'Article 4, nous verrons une autre façon de combiner des tables, non pas horizontalement, mais verticalement. Nous allons jouer aux Lego avec nos bases de données grâce aux opérations ensemblistes (UNION, INTERSECT, EXCEPT).

Nicolas Housset

Passionné d'informatique, je suis Consultant et expert technique SAS VIYA, également co-fondateur de la société Flexcelite. Spécialisé dans les technologies SAS (Viya, 9.4) et les infrastructures associées (Linux, Hadoop, Azure), ce blog est mon espace pour partager mes mémos techniques et retours d'expérience.