TUTORIEL · QLIK SENSE
JOIN dans Qlik Sense
LEFT, INNER, RIGHT ou OUTER : visualisez ce que chaque jointure conserve et apprenez à éviter le produit cartésien et la multiplication des lignes.
Comprendre le JOIN dans Qlik
JOIN permet de fusionner les données de deux chargements dans une seule table Qlik.
Avant un JOIN, identifiez toujours précisément les champs communs entre les deux chargements.
Exemple
| Table | Champs |
|---|---|
| VENTES | ID_CLIENT · ID_VENTE · MONTANT |
| CLIENTS | ID_CLIENT · NOM_CLIENT |
| Après JOIN | ID_CLIENT · ID_VENTE · MONTANT · NOM_CLIENT |
Le point essentiel
Dans cet exemple, ID_CLIENT porte le même nom dans les deux tables : Qlik l’utilise comme champ commun pour effectuer la jointure.
| JOIN | fusionne les données dans une seule table |
|---|---|
| Clé | champ portant le même nom dans les deux chargements |
| Clause ON | il n’y en a pas dans le JOIN du script Qlik |
| Plusieurs champs communs | ils participent tous à la jointure |
Nos deux tables de départ
Nous allons utiliser les mêmes données dans tout le tutoriel afin de voir exactement ce que chaque type de JOIN conserve.
Ces deux lignes sans correspondance vont nous permettre de voir immédiatement la différence entre LEFT, INNER, RIGHT et OUTER JOIN.
Exemple
| ID_VENTE | ID_CLIENT | MONTANT |
|---|---|---|
| V001 | C001 | 50 |
| V002 | C002 | 120 |
| V003 | C001 | 75 |
| V004 | C004 | 90 |
| ID_CLIENT | NOM_CLIENT |
|---|---|
| C001 | Martin |
| C002 | Durand |
| C003 | Bernard |
C004 : une vente sans client correspondant C003 : un client sans vente correspondante
| Champ commun | ID_CLIENT |
|---|---|
| C001 | 2 ventes |
| C004 | présent uniquement dans VENTES |
| C003 | présent uniquement dans CLIENTS |
LEFT JOIN : conserver toutes les ventes
LEFT JOIN conserve toutes les lignes de la table cible et ajoute les informations de la seconde table lorsqu’une correspondance existe.
C’est un cas classique : enrichir une table de faits avec une information de référence sans perdre les lignes de la table principale.
Exemple
VENTES:
LOAD ID_VENTE, ID_CLIENT, MONTANT
FROM [lib://Donnees/VENTES.qvd] (qvd);
LEFT JOIN (VENTES)
LOAD ID_CLIENT, NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
APRÈS LE LEFT JOIN
| ID_VENTE | ID_CLIENT | MONTANT | NOM_CLIENT |
|---|---|---|---|
| V001 | C001 | 50 | Martin |
| V002 | C002 | 120 | Durand |
| V003 | C001 | 75 | Martin |
| V004 | C004 | 90 | NULL |
| VENTES | toutes les lignes sont conservées |
|---|---|
| CLIENTS | apporte NOM_CLIENT lorsqu’il existe |
| C004 | reste présent |
| NOM_CLIENT de C004 | NULL |
INNER JOIN : ne garder que les correspondances
INNER JOIN ne conserve que les données pour lesquelles Qlik trouve une correspondance entre les deux chargements.
INNER JOIN est utile lorsque seules les lignes possédant réellement une correspondance nous intéressent.
Exemple
VENTES:
LOAD ID_VENTE, ID_CLIENT, MONTANT
FROM [lib://Donnees/VENTES.qvd] (qvd);
INNER JOIN (VENTES)
LOAD ID_CLIENT, NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
APRÈS LE INNER JOIN
| ID_VENTE | ID_CLIENT | MONTANT | NOM_CLIENT |
|---|---|---|---|
| V001 | C001 | 50 | Martin |
| V002 | C002 | 120 | Durand |
| V003 | C001 | 75 | Martin |
| C001 | conservé |
|---|---|
| C002 | conservé |
| C004 | supprimé : aucune correspondance |
| C003 | absent : aucune vente |
RIGHT et OUTER JOIN
RIGHT JOIN change le côté que l’on souhaite conserver. OUTER JOIN conserve les données provenant des deux côtés.
Dans la pratique, LEFT JOIN est souvent plus intuitif pour enrichir une table principale. RIGHT JOIN répond à des cas plus spécifiques.
Exemple
RIGHT JOIN
RIGHT JOIN (VENTES)
LOAD ID_CLIENT, NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
| VENTE | CLIENT | NOM |
|---|---|---|
| V001 | C001 | Martin |
| V003 | C001 | Martin |
| V002 | C002 | Durand |
| NULL | C003 | Bernard |
OUTER JOIN
OUTER JOIN (VENTES)
LOAD ID_CLIENT, NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
| VENTE | CLIENT | NOM |
|---|---|---|
| V001 | C001 | Martin |
| V003 | C001 | Martin |
| V002 | C002 | Durand |
| V004 | C004 | NULL |
| NULL | C003 | Bernard |
JOIN tout court ?
Dans le script Qlik, si vous écrivez simplement JOIN sans LEFT, INNER ou RIGHT, le comportement par défaut est celui d’un OUTER JOIN.
| RIGHT JOIN | conserve toutes les lignes du chargement entrant |
|---|---|
| OUTER JOIN | conserve les lignes des deux côtés |
| JOIN sans qualificatif | OUTER JOIN |
| Valeur sans correspondance | champs opposés à NULL |
Le piège : le produit cartésien
Voici probablement le contrôle le plus important à faire avant un JOIN Qlik : vérifier qu’il existe bien le ou les champs communs attendus.
Ce n’est pas seulement un problème de résultat fonctionnel : sur de gros volumes, une jointure cartésienne accidentelle peut saturer les ressources disponibles et faire échouer le rechargement.
Exemple
🚨 AUCUN CHAMP COMMUN = PRODUIT CARTÉSIEN
Table A100 000 lignes
×
Table B50 000 lignes
=
5 000 000 000combinaisons potentielles
Un simple champ mal nommé peut donc transformer un chargement parfaitement banal en une quantité gigantesque de données à traiter.
// ATTENTION : les champs ne portent pas le même nom !
VENTES:
LOAD ID_VENTE, ID_CLIENT, MONTANT
FROM [lib://Donnees/VENTES.qvd] (qvd);
LEFT JOIN (VENTES)
LOAD
CODE_CLIENT, // ← pas de champ ID_CLIENT !
NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
// VENTES et CLIENTS n'ont ici aucun champ commun.
// Le JOIN devient un produit cartésien.
🛑 Le réflexe SOSBI avant de lancer le script
- Identifier la clé attendue.
- Vérifier qu’elle porte exactement le même nom dans les deux LOAD.
- Vérifier les autres champs homonymes : ils participeront eux aussi à la jointure.
- Contrôler la cardinalité de la clé avant de travailler sur de gros volumes.
| 0 champ commun | produit cartésien |
|---|---|
| 100 000 × 50 000 | 5 milliards de combinaisons potentielles |
| Nom des champs | doit être contrôlé avant le JOIN |
| Gros volumes | tester et contrôler avant production |
Avoir une clé ne suffit pas
Un champ commun évite le produit cartésien total, mais cela ne garantit pas que le nombre de lignes restera stable.
Après un JOIN important, comparer le nombre de lignes avant et après est un excellent contrôle de cohérence.
Exemple
1 → 1 Cas simple
Une vente trouve une seule ligne de référence.
1 × 1 → 1 ligne
1 → N À comprendre
Une ligne trouve plusieurs correspondances.
1 × 3 → 3 lignes
N ↔ N Danger de multiplication
Plusieurs lignes correspondent à plusieurs lignes.
4 × 5 → 20 lignes pour cette clé
Exemple classique
Vous pensez joindre une table de référence contenant une ligne par client.
Mais ID_CLIENT = C001 apparaît trois fois dans cette table.
Chaque ligne de VENTES portant C001 peut alors être reproduite trois fois.
| 1 → 1 | pas de multiplication pour la clé |
|---|---|
| 1 → N | une ligne peut devenir plusieurs lignes |
| N ↔ N | multiplication des correspondances |
| Contrôle | vérifier l’unicité lorsque le modèle l’exige |
JOIN, association ou KEEP : que choisir ?
Dans Qlik, JOIN n’est pas le réflexe obligatoire. Le modèle associatif permet souvent de conserver les tables séparées.
Un JOIN doit répondre à un besoin identifié. Dans Qlik, fusionner systématiquement les tables n’est pas une obligation.
Exemple
Association
Les tables restent séparées et sont reliées par leurs champs communs.
À privilégier lorsque le modèle associatif répond naturellement au besoin.JOIN
Les données sont réellement fusionnées dans une même table.
À utiliser lorsqu’une fusion est réellement souhaitée.✂ KEEP
Les ensembles sont réduits selon leurs correspondances mais restent séparés.
Utile lorsque l’on veut filtrer sans fusionner.Avant de faire un JOIN Avant d’écrire JOIN, posez-vous trois questions :
- Ai-je réellement besoin de fusionner ces deux tables ?
- Quels sont exactement les champs communs ?
- Quelle est la cardinalité de ma clé ?
| Association | tables séparées |
|---|---|
| JOIN | une seule table résultante |
| KEEP | réduit les ensembles sans les fusionner |
| Avant JOIN | champs communs + cardinalité |