Clause WHERE sous SAS
Sélectionnez vos observations avec la clause WHERE
A l'instar des instructions SQL, la clause WHERE sous SAS va nous permettre de sélectionner
les observations d'une table en précisant un ou plusieurs critères. L'instruction WHERE va
pouvoir être utilisée dans une étape DATA et dans la majorité des étapes PROC. Attention cependant,
il n'est en effet possible de mentionner qu'une seule instruction WHERE, que ce soit dans une étape DATA
ou PROC. Dans le cas contraire, seule la dernière instruction WHERE sera appliquée aux données.
Voyons plus en détails comment s'écrit une clause WHERE sous SAS.
Données de travail
Nous allons travailler avec une base des membres d'une salle de sport, ce set comporte 5 colonnes, à savoir l'identifiant du membre, son âge, son sexe (H ou F), son prénom ainsi que sa date d'inscription dans la salle. Le set compte 56 membres. Chargeons tout d'abord les données puis voyons à quoi elles ressemblent.
options validvarname=any;
filename FILE "/home/u49997643/gorenja/salle_sport.csv"
encoding='utf-8' ;
proc import datafile=FILE out=work.sport dbms=csv replace;
delimiter = ';';
getnames = yes;
run;
proc print data=work.sport;
format inscription date9.;
run;

Opérateurs de comparaison
Nous retrouvons les opérateurs de base, comme listés ci-dessous. A noter qu'il est possible d'employer aussi bien le symbole mathématique que la contraction. A noter également que deux symboles distincts sont possibles pour exprimer la négation. Par ailleurs un filtre plus complexe comme l'inclusion dans un ensemble ne pourra se faire que va la contraction IN.

Ci-dessous quelque exemple d'utilisation.
/*Edition des membres ages de 60 ans ou plus */
proc print data=work.sport;
where age GE 60;
run;
/*Edition des membres feminines uniquement */
proc print data=work.sport;
where sexe = 'F';
run;
/*Edition des membres inscrits avant le 1er janvier 2020 */
proc print data=work.sport;
where inscription < "01JAN2020"d;
format inscription date9.;
run;
/*Edition de certains membres dont le prenom commence par Jean */
proc print data=work.sport;
where prenom IN ("Jean", "Jean-Baptiste", "Jean-Marie");
run;
Vous noterez que le dernier exemple est loin d'être efficace si l'objectif est d'afficher réellement tous les prénoms commençant par Jean. Nous reviendrons sur ce point.
Opérateurs logiques
Ci-dessous les opérateurs logiques tels que SAS peut les interpréter. Nous avons déjà
précisé qu'une seule instruction WHERE n'est autorisée par étape, les opérateurs logiques
vont donc nous aider à étendre le spectre d'application des filtres.
Il faut préciser enfin que les parenthèses nous serviront à dicter les priorités.

/*Exemple de selection multiple */
proc print data=work.sport;
WHERE (age = 59 | age = 60) & sexe = "F" & inscription >= "01JAN2020"d;
FORMAT inscription date9.;
run;
Opérateurs spéciaux
Nous terminons par les opérateurs spéciaux, ainsi nommés car ils sont issus d'une mécanique sous-jacente plus complexe. Ci-dessous les opérateurs que nous allons détailler un par un.

Opérateur CONTAINS
Il s'agit ici de déterminer si une sous-chaine donnée est incluses dans une chaine de caractères, quelle que soit sa position. Cet opérateur est sensible à la casse. Par ailleurs, CONTAINS peut également être appelé via l'abréviation ?, ainsi les deux exemples ci-dessous vont donner le même résultat :
/*Tous les membres dont le prenom contient 'Marie' */
proc print data=work.sport;
where prenom ? 'Marie';
run;
proc print data=work.sport;
where prenom contains 'Marie';
run;
Opérateur LIKE
L'opérateur LIKE va chercher tous les enregistrements dont la valeur du champs requeté répond au masque (ou pattern) indiqué. Pour rappel, nous avions dans un précèdent exemple cherche à éditer les membres dont le prénom commence par Jean. Avec LIKE il nous suffira de faire ceci :
proc print data=work.sport;
where prenom like 'Jean%';
run;
Vous noterez le caractère % qui vous nous permettre d'indiquer à SAS qu'un ou plusieurs caractères suivent. Si nous
voulons lui signifier qu'un caractère exactement doit être pris en compte, le caractère _ sera utilisé.
Ainsi, si vous voulons tous les membres dont la seconde lettre du prénom est un e, l'instruction WHERE va ressembler
à ceci :
proc print data=work.sport;
where prenom like '_e%';
run;
Opérateur BETWEEN-AND
L'opérateur BETWEEN-AND est assez intuitif dans son utilisation, il va nous permettre de sélectionner des enregistrements dont la valeur du champs requêté est comprise entre 2 bornes. Ces bornes sont incluses dans la sélection. Par ailleurs cet opérateur s'applique aussi bien aux valeurs numériques que caractères.
/*Tous les membres dont l'age est compris entre 40 et 50 ans */
proc print data=work.sport;
where age between 40 and 50;
run;
/*Tous les membres dont le prenom commence par A, B ou est egal a C */
proc print data=work.sport;
where prenom between 'A' and 'C';
run;
/*Tous les membres dont l'inscription est comprise entre
le 01 Juin 2020 et le 31 aout 2020 */
proc print data=work.sport;
where inscription between '01JUN2020'd and '31AUG2020'd;
format inscription date9.;
run;
Dans le cas d'un bornage sur une chaine de caractères, comme illustré dans le second exemple ci-dessus, il convient de faire attention à deux choses. D'une part l'opérateur est sensible à la casse, et d'autre part, la borne supérieure peut prêter a confusion. Dans notre exemple, vont ressortir les prénoms valant ou commençant par A, les prénoms valant ou commençant par B ainsi que les prénoms valant C. Les prénoms commençant par C ne seront en effet pas inclus car en dehors de la plage.
Opérateur WHERE ALSO / WHERE SAME AND
Nous avons précisé en débutant l'article qu'un seul WHERE n'était autorisé par étape. Ainsi, lister plusieurs WHERE de suite
aboutira à la prise en compte du dernier uniquement. Les opérateurs logiques, dont nous avons déjà parlés, peuvent nous aider
à procéder a une sélection multiple, et c'est d'ailleurs la solution à privilégier. Néanmoins, une autre solution s'offre à nous.
Il s'agit d'unir plusieurs clauses WHERE via les instructions WHERE SAME et WHERE ALSO. On parle alors d'augmentation. Cette solution
peut s'avérer utile pour conserver un code lisible.
Concrètement chaque instruction WHERE ALSO va augmenter l'instruction précédente de filtres supplémentaires. Il faut donc considérer un
"et" logique entre chaque. L'instruction WHERE SAME AND constitue la même instruction, celle-ci est néanmoins plus compréhensible peut-être
dans la mesure ou le terme AND apparait clairement.
/* femme de 65 ans dont le prenom contient 'Louise' */
proc print data=work.sport;
where sexe='F';
where also age = 65;
where also prenom contains 'Louise';
run;
Opérateur IS NULL / IS MISSING
Les opérateurs IS NULL et IS MISSING sélectionnent tous deux les enregistrements dont la valeur du champs requêté
est manquante. Pour le type chaine, une donnée manquante aura pour valeur '', pour les types numériques une donnée
manquante aura pour valeur . (le point). On peut donc considérer que IS NULL ou IS MISSING sont les équivalents de
var_num = . ou var_car = ''
Enfin, précision que les sélections inverses, toutes aussi utiles, sinon plus, s'écriront IS NOT NULL et IS NOT MISSING.
/* Observations dont le sexe est bien renseigne */
proc print data=work.sport;
where sexe is not missing;
run;
Retrouvez dans la rubrique "Nos datasets" toutes les données dont vous aurez besoin pour tester et pratiquer !