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.

Contrairement à SQL, on n’écrit pas de clause ON dans un JOIN Qlik. Qlik rapproche automatiquement les données à partir de tous les champs portant exactement le même nom dans les deux chargements.

Avant un JOIN, identifiez toujours précisément les champs communs entre les deux chargements.

Exemple

TableChamps
VENTESID_CLIENT · ID_VENTE · MONTANT
CLIENTSID_CLIENT · NOM_CLIENT
Après JOINID_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.

JOINfusionne les données dans une seule table
Cléchamp portant le même nom dans les deux chargements
Clause ONil n’y en a pas dans le JOIN du script Qlik
Plusieurs champs communsils 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.

VENTES contient quatre ventes. CLIENTS contient trois clients. Le client C004 existe dans VENTES mais pas dans CLIENTS. À l’inverse, C003 existe dans CLIENTS mais n’a aucune vente.

Ces deux lignes sans correspondance vont nous permettre de voir immédiatement la différence entre LEFT, INNER, RIGHT et OUTER JOIN.

Exemple

VENTES.qvd
ID_VENTEID_CLIENTMONTANT
V001C00150
V002C002120
V003C00175
V004C00490
CLIENTS.qvd
ID_CLIENTNOM_CLIENT
C001Martin
C002Durand
C003Bernard

C004 : une vente sans client correspondant C003 : un client sans vente correspondante

Champ communID_CLIENT
C0012 ventes
C004présent uniquement dans VENTES
C003pré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.

Nous chargeons d’abord VENTES. Elle devient donc notre table cible. CLIENTS est ensuite joint à VENTES grâce au champ commun ID_CLIENT.

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_VENTEID_CLIENTMONTANTNOM_CLIENT
V001C00150Martin
V002C002120Durand
V003C00175Martin
V004C00490NULL
VENTEStoutes les lignes sont conservées
CLIENTSapporte NOM_CLIENT lorsqu’il existe
C004reste présent
NOM_CLIENT de C004NULL

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.

C004 disparaît puisqu’il n’existe pas dans CLIENTS. C003 n’apparaît pas non plus puisqu’il n’existe aucune vente pour ce client.

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_VENTEID_CLIENTMONTANTNOM_CLIENT
V001C00150Martin
V002C002120Durand
V003C00175Martin
C001conservé
C002conservé
C004supprimé : aucune correspondance
C003absent : 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.

Avec RIGHT JOIN, tous les clients du chargement entrant sont conservés : C003 apparaît donc même sans vente. Avec OUTER JOIN, on conserve à la fois C003 et la vente de C004.

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);
VENTECLIENTNOM
V001C001Martin
V003C001Martin
V002C002Durand
NULLC003Bernard

OUTER JOIN

OUTER JOIN (VENTES)
LOAD ID_CLIENT, NOM_CLIENT
FROM [lib://Donnees/CLIENTS.qvd] (qvd);
VENTECLIENTNOM
V001C001Martin
V003C001Martin
V002C002Durand
V004C004NULL
NULLC003Bernard

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 JOINconserve toutes les lignes du chargement entrant
OUTER JOINconserve les lignes des deux côtés
JOIN sans qualificatifOUTER JOIN
Valeur sans correspondancechamps 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.

Qlik n’utilise pas de clause ON pour le JOIN du script. Il recherche les champs portant le même nom. Si aucun champ n’est commun aux deux chargements, aucune clé ne permet de rapprocher les lignes : Qlik combine alors chaque ligne de la première table avec chaque ligne de la seconde.

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

  1. Identifier la clé attendue.
  2. Vérifier qu’elle porte exactement le même nom dans les deux LOAD.
  3. Vérifier les autres champs homonymes : ils participeront eux aussi à la jointure.
  4. Contrôler la cardinalité de la clé avant de travailler sur de gros volumes.

0 champ communproduit cartésien
100 000 × 50 0005 milliards de combinaisons potentielles
Nom des champsdoit être contrôlé avant le JOIN
Gros volumestester 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.

Avant d’enrichir une table, il faut aussi connaître la cardinalité de la clé. Si une même clé apparaît plusieurs fois des deux côtés, les correspondances se multiplient.

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 → 1pas de multiplication pour la clé
1 → Nune ligne peut devenir plusieurs lignes
N ↔ Nmultiplication des correspondances
Contrôlevé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.

Utilisez JOIN lorsqu’une vraie fusion apporte quelque chose au modèle. Si les tables ont vocation à rester distinctes, l’association naturelle de Qlik est souvent plus simple. KEEP permet quant à lui de réduire les ensembles tout en conservant des 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 :

  1. Ai-je réellement besoin de fusionner ces deux tables ?
  2. Quels sont exactement les champs communs ?
  3. Quelle est la cardinalité de ma clé ?

Associationtables séparées
JOINune seule table résultante
KEEPréduit les ensembles sans les fusionner
Avant JOINchamps communs + cardinalité