Proc SQL

Le piège du "Many-to-Many" (MERGE vs SQL)

Simon 24/08/2019 1 vistas

Une croyance répandue veut que l'instruction MERGE de l'étape DATA soit l'équivalent exact d'une jointure SQL (LEFT JOIN ou FULL JOIN). Si cela est vrai pour des relations simples (1-pour-1 ou 1-pour-N), c'est totalement faux pour des relations de type "Many-to-Many" (N-pour-N).

Le constat : Des résultats divergents

Prenons un exemple simple où la clé de jointure (ID) apparaît plusieurs fois dans les deux tables :

  • Table 1 : ID 23456 apparaît 2 fois.

  • Table 2 : ID 23456 apparaît 2 fois.

Si nous cherchons à combiner ces données, nous nous attendons mathématiquement à obtenir $2 \times 2 = 4$ lignes (le produit cartésien pour cet ID).

Note :
L'approche PROC SQL (Produit Cartésien)
Le SQL fonctionne sur une logique d'ensemble (algèbres relationnelle). Il combine chaque ligne de la table A avec chaque ligne correspondante de la table B.
1PROC SQL;
2 SELECT * FROM dataset1 t1
3 LEFT JOIN dataset2 t2 ON t1.ID = t2.ID;
4QUIT;
Résultat : 4 lignes pour l'ID 23456. Toutes les combinaisons possibles sont créées. C'est le comportement standard d'une base de données relationnelle.
Note :
L'approche DATA MERGE (Juxtaposition séquentielle)
L'étape DATA fonctionne ligne par ligne de manière séquentielle. Elle place les pointeurs de lecture "côte à côte".
1DATA temp;
2 MERGE dataset1 dataset2;
3 BY ID;
4RUN;
2 lignes seulement pour l'ID 23456.

Que s'est-il passé ? SAS© a lu la 1ère occurrence de l'ID dans la Table 1 et l'a associée à la 1ère occurrence de la Table 2. Puis, il a lu la 2ème occurrence de la Table 1 et l'a associée à la 2ème de la Table 2. Comme il n'y a plus de données pour cet ID dans aucune des deux tables, il passe à l'ID suivant.

Si la Table 1 avait 2 lignes et la Table 2 en avait 3 pour le même ID, SAS© aurait produit 3 lignes, la dernière ligne de la Table 1 étant "retenue" (valeurs conservées) pour remplir le vide face à la 3ème ligne de la Table 2.

Conclusion : Lequel choisir ?

  • Utilisez PROC SQL si vous avez besoin d'un produit cartésien (relation N-pour-N), c'est-à-dire croiser toutes les occurrences possibles. C'est souvent le résultat attendu pour des analyses croisées.

  • Utilisez DATA MERGE pour des relations 1-pour-1 ou 1-pour-N (type "Look-up" / Enrichissement de données). C'est beaucoup plus performant en termes de temps de calcul sur de gros volumes, tant que les clés sont uniques dans au moins l'une des deux tables.

Note technique : Il est techniquement possible de simuler un produit cartésien avec une étape DATA (en utilisant deux instructions SET et des boucles explicites), mais le code devient inutilement complexe. Dans ce cas précis, la clarté du SQL est imbattable.