SAS et SQL : Comment répliquer OVER PARTITION BY dans SAS
Simon 10 vues
Niveau de difficulté
Débutant
Publié le :
Le mot de l'Expert
Par Simon
Ne voyez pas l'absence de PARTITION BY dans PROC SQL comme une lacune, mais comme une opportunité de performance. L'étape DATA avec le traitement par groupe (BY) est souvent bien plus rapide que les Window Functions SQL : en exploitant la logique séquentielle (FIRST., RETAIN), vous traitez vos données complexes en une seule passe mémoire, là où le moteur SQL multiplierait les lectures.
/* 1. Le tri est obligatoire pour utiliser BY */
proc sort data=transactions;
by customer_id trans_date;
run;
/* 2. Le Data Step */
data want;
set transactions;
by customer_id;
/* Si c'est la première ligne du client, on remet le compteur à 1 */
if first.customer_id then row_num = 1;
/* Sinon, on incrémente */
else row_num + 1;
run;
1
/* 1. Le tri est obligatoire pour utiliser BY */
2
PROC SORTDATA=transactions;
3
BY customer_id trans_date;
4
RUN;
5
6
/* 2. Le Data Step */
7
DATA want;
8
SET transactions;
9
BY customer_id;
10
11
/* Si c'est la première ligne du client, on remet le compteur à 1 */
12
IF first.customer_id THEN row_num = 1;
13
/* Sinon, on incrémente */
14
ELSE row_num + 1;
15
RUN;
Exemple : Répliquer un Cumulative SUM
En SQL standard :SUM(amount) OVER (PARTITION BY customer_id ORDER BY date)
data want;
set transactions;
by customer_id;
/* RETAIN garde la valeur de la ligne précédente */
retain running_total;
if first.customer_id then running_total = amount;
else running_total = running_total + amount;
run;
1
DATA want;
2
SET transactions;
3
BY customer_id;
4
5
/* RETAIN garde la valeur de la ligne précédente */
proc sql;
connect to oracle (user=... pass=... path=...);
create table want as
select * from connection to oracle
(
/* Ici, vous pouvez utiliser toute la syntaxe Oracle,
y compris les fonctions de fenêtrage */
SELECT
customer_id,
trans_date,
RANK() OVER (PARTITION BY customer_id ORDER BY trans_date DESC) as rang
FROM
schema.transactions
);
disconnect from oracle;
quit;
1
PROC SQL;
2
connect to oracle (user=... pass=... path=...);
3
4
create TABLE want as
5
select * from connection to oracle
6
(
7
/* Ici, vous pouvez utiliser toute la syntaxe Oracle,
8
y compris les fonctions de fenêtrage */
9
SELECT
10
customer_id,
11
trans_date,
12
RANK() OVER (PARTITION BY customer_id ORDER BY trans_date DESC) as rang
13
FROM
14
schema.transactions
15
);
16
17
disconnect from oracle;
18
QUIT;
Avantage : Vous utilisez la syntaxe SQL que vous connaissez déjà et profitez de la puissance du serveur SGBD.
proc rank data=transactions out=want descending;
by customer_id; /* Équivalent du PARTITION BY */
var amount; /* La variable sur laquelle on classe */
ranks my_rank; /* Le nom de la nouvelle colonne */
run;
1
PROC RANKDATA=transactions out=want descending;
2
BY customer_id; /* Équivalent du PARTITION BY */
3
var amount; /* La variable sur laquelle on classe */
4
ranks my_rank; /* Le nom de la nouvelle colonne */
Restez sur PROC SQL standard (sans window functions).
Avertissement important
Les codes et exemples fournis sur WeAreCAS.eu sont à but pédagogique. Il est impératif de ne pas les copier-coller aveuglément sur vos environnements de production. La meilleure approche consiste à comprendre la logique avant de l'appliquer. Nous vous recommandons vivement de tester ces scripts dans un environnement de test (Sandbox/Dev). WeAreCAS décline toute responsabilité quant aux éventuels impacts ou pertes de données sur vos systèmes.
SAS et tous les autres noms de produits ou de services de SAS Institute Inc. sont des marques déposées ou des marques de commerce de SAS Institute Inc. aux États-Unis et dans d'autres pays. ® indique un enregistrement aux États-Unis. WeAreCAS est un site communautaire indépendant et n'est pas affilié à SAS Institute Inc.
Ce site utilise des cookies techniques et analytiques pour améliorer votre expérience.
En savoir plus.