IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SAS Base Discussion :

[WHERE] Meilleur placement pour une clause WHERE


Sujet :

SAS Base

  1. #1
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 347
    Points : 235
    Points
    235
    Par défaut [WHERE] Meilleur placement pour une clause WHERE
    Bonjour,

    J'ai une question sur la clause WHERE. Je sais qu'elle est (quand on peut s'en servir) plus rapide d'exécution que IF, car elle teste les conditions avant lecture des observations.

    En revanche je ne sais pas quelle "syntaxe" (je ne sais pas si j'utilise le bon terme) est le plus approprié pour son utilisation. Je sais que l'on peut utiliser WHERE soit au moment du SET, soit dans le corps de l'étape DATA.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    data __test1;
    	set sashelp.cars (where=(Type="SUV"));
    run;
     
    data __test2;
    	set sashelp.cars;
    	where Type="SUV";
    run;
    Je sais que pour du KEEP/DROP il est préférable de les placer directement dans DATA et/ou SET, mais je ne trouve rien pour WHERE.

    Avez-vous une idée ?

    Merci beaucoup,

    alers

  2. #2
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    Hello,

    si tu n'as aucune opération à faire sur le champ en question, alors le mieux c'est de placer ton where dans le SET, cela permet de limiter les données remontées en mémoire.
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  3. #3
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 347
    Points : 235
    Points
    235
    Par défaut
    Bonsoir et merci pour ta réponse.

    Je n'ai pas totalement compris ce que tu entends par "opération". Par exemple, si je fais ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    data __test;
    set sashelp.class (where=(weight*2<120));
    run;
    il vaut mieux mettre le WHERE dans l'étape DATA et pas dans le SET ?

  4. #4
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    Hello,

    Si tu n'as besoin de toutes les valeurs du champ weight , alors oui il vaut mieux l'utiliser dans le SET. donc dans ton Exemple, le mieux c'est de le placer dans le SET.

    Un exemple où on ne peut pas filtrer à l'entrer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    data __test;
    set sashelp.class ;
    if weight*2<120 then poids='catégorie A ';
    length poids $15;
    run;
    Dans cet exemple j'ai besoin de toutes les valeurs de la variable weight pour calculer la variable poids. donc le filtre est à positionner dans le DATA ( en sortie) .
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  5. #5
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 347
    Points : 235
    Points
    235
    Par défaut
    Bonjour et merci.

    Dans ce cas là tu utilises un IF. Ce serait indispensable si je voulais conserver toutes les observations. Mais en imaginant que je ne veuille que la "Catégorie A", j'imagine que je pourrais faire ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    data __test;
    set sashelp.class (where=(weight*2<120)) ;
    poids='catégorie A ';
    length poids $15;
    run;
    Merci encore !

    alers

  6. #6
    Membre actif
    Inscrit en
    Juillet 2010
    Messages
    199
    Détails du profil
    Informations forums :
    Inscription : Juillet 2010
    Messages : 199
    Points : 214
    Points
    214
    Par défaut
    Bonjour,

    J'ai fait un petit test pour vérifier

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    %Macro RunTime(BGN_END);
    %GLOBAL runbegin runend rundiff;
    %If &BGN_END EQ %Then %Do; /* use BEGIN by default if no parameter value is
    specified */
    %let BGN_END= BEGIN;
    %End;
    %If %Upcase(&BGN_END) = BEGIN %Then %Do; /*report BEGIN time */
    %Let runbegin = %Sysfunc(Datetime());
    %Let runend =;
    %Let msg = NOTE: The specified block of code BEGAN AT %Sysfunc(Sum(&runbegin),
    Datetime16.).;
    %End; %Else
    %If %Upcase(&BGN_END) = END %Then %Do; /*report END time and calculate elapsed
    time*/
    %Let runend = %Sysfunc(Datetime());
    %Let rundiff = %Sysfunc(Sum(&&runend, -&&runbegin));
    %Let msg = NOTE: The specified block of code ENDED AT %Sysfunc(Sum(&&runend),
    Datetime16.).;
    %Let msg = &msg....Elapsed time of (hh:mm:ss): %Sysfunc(Sum(&rundiff), Time8.);
    %End;
    %Else %Do; /*To print error message if other parameter value than BEGIN and END is
    used*/
    Options Nosource;
    %Let runbegin =%Sysfunc(Datetime());
    %Let runend =%Sysfunc(Datetime());
    %Put;%Put;
    %Put ERROR- NOTE: Wrong parameter. Please use RunTime(BEGIN) or RunTime(END).;
    %Put; %Put;
    Options Source;
    %goto SKIP; /*Skip to end of the macro*/
    %End;
    Options Nosource;
    %Put;%Put;
    %Put %Superq(msg); /*Print the running time message*/
    %Put;%Put;
    Options Source;
    %SKIP: /*end of macro*/
    %Mend RunTime;
     
     
    %LET mult = 10000;
    DATA table;
    	SET sashelp.cars;
    	DO i = 1 to &mult.;
    	OUTPUT;
    	END;
    RUN;
     
    /* Test 1 */
    PROC DATASETS LIB=WORK NOLIST NODETAILS NOWARN;
    	DELETE triee ;
    RUN ; QUIT ;
    PROC SORT DATA = table OUT = triee;
    	BY origin make;
    RUN;
     
    %RunTime(BEGIN);
    DATA triee2;
    SET triee;
    IF type = 'Wagon';
    RUN;
    %RunTime(End);
     
    /*
    NOTE: The specified block of code ENDED AT 04NOV15:10:31:42....Elapsed time of (hh:mm:ss):  0:00:02
    */
     
    /* Test 2 */
    PROC DATASETS LIB=WORK NOLIST NODETAILS NOWARN;
    	DELETE triee ;
    RUN ; QUIT ;
    PROC SORT DATA = table OUT = triee;
    	BY origin make;
    RUN;
     
    %RunTime(BEGIN);
    DATA triee2;
    SET triee;
    WHERE type = 'Wagon';
    RUN;
    %RunTime(End);
     
    /*
    NOTE: The specified block of code ENDED AT 04NOV15:10:32:10....Elapsed time of (hh:mm:ss):  0:00:01
    */
     
     
    /* Test 3 */
    PROC DATASETS LIB=WORK NOLIST NODETAILS NOWARN;
    	DELETE triee ;
    RUN ; QUIT ;
    PROC SORT DATA = table OUT = triee;
    	BY origin make;
    RUN;
     
    %RunTime(BEGIN);
    DATA triee2;
    SET triee(WHERE= (type = 'Wagon'));
    RUN;
    %RunTime(End);
    /*
    NOTE: The specified block of code ENDED AT 04NOV15:10:32:35....Elapsed time of (hh:mm:ss):  0:00:01
    */
    Dans ces trois test ce sont les deux clauses WHERE qui sont plus performantes que le IF.
    Il faudrait peut-être augmenter le volume de la base pour que ce soit plus net.

  7. #7
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 347
    Points : 235
    Points
    235
    Par défaut
    De manière générale j'utilise WHERE quand je veux sélectionner des observations uniquement.

    Dans l'exemple de s_a_m, j'aurais utilisé IF si je voulais créer la catégorie A et la catégorie B pour le reste et conserver les deux catégories (toutes les observations).

    Sinon c'est amusant parce que sur mon ordinateur avec SAS 9.3 le dernier test, avec WHERE dans le SET, donc supposément le plus rapide, est en fait le plus long avec 0:00:01 alors que les deux autres sont à 0:00:00.

    J'essaierai de plus gros datasets.

    EDIT :

    Oui en effet avec un multiplicateur de 100000 (bonjour le temps pour trier la table au début) on voit bien la différence. Il m'a fallu 16 secondes avec IF, 3 avec WHERE, et 4 avec WHERE dans le SET (donc un tout petit peu plus de temps).

    J'imagine que si je teste avec un zéro en plus on verra mieux la différence entre les deux WHERE et qui sait le troisième sera en fait plus rapide.

  8. #8
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2011
    Messages : 1 624
    Points : 3 402
    Points
    3 402
    Par défaut
    Hello,

    La différence entre le IF et le WHERE dans une étape data est : IF s'applique sur les données lues et/ou créées dans une étape data, En revanche le WHERE s'applique uniquement sur les données lues.

    Pour revenir au sujet initial, c'est facile de savoir où il faut placer ton WHERE. il suffit de se poser la question suivante :

    Est ce que j'ai besoin de toutes les données de la table en entrée pour mes traitements dans l'étape data ?
    ===> Si oui, le where est à placer en sortie ( dans le DATA)
    ===>Si non, le filtre est à placer en entrée ( dans le SET )
    N'oubliez pas de consulter les FAQ SAS et les cours et tutoriels SAS
    N'oubliez pas de mettre votre message à si la solution donnée résout votre problème

  9. #9
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Citation Envoyé par alers Voir le message
    Bonjour,
    En revanche je ne sais pas quelle "syntaxe" (je ne sais pas si j'utilise le bon terme) est le plus approprié pour son utilisation. Je sais que l'on peut utiliser WHERE soit au moment du SET, soit dans le corps de l'étape DATA.
    C'est pareil, la clause WHERE en tant qu'instruction dans l'étape DATA ou en tant qu'option dans le SET permet à SAS de restreindre la lecture des données avant leur insertion dans le PDV.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Data toto;
    set titi;
    where mavar=2;
    run;
     
    Data toto;
    set titi (where=(mavar=2));
    run;
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

  10. #10
    Membre actif
    Homme Profil pro
    Inscrit en
    Février 2013
    Messages
    347
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Février 2013
    Messages : 347
    Points : 235
    Points
    235
    Par défaut
    D'accord donc en gros on le mets dans le SET si on veut éviter une ligne de code en plus.

    Merci !

  11. #11
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    Je le mets en instruction pour éviter les parenthèses et un =
    N'oubliez pas de cliquer sur lorsque votre problème est réglé !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 07/01/2014, 11h46
  2. Réponses: 4
    Dernier message: 23/10/2009, 00h18
  3. Meilleur endroit pour la clause WHERE
    Par zoubidaman dans le forum Langage SQL
    Réponses: 1
    Dernier message: 16/10/2007, 12h16
  4. Une clause WHERE avant un LEFT JOIN ?
    Par bugalood dans le forum Langage SQL
    Réponses: 11
    Dernier message: 27/07/2005, 14h22
  5. [super requete] Dumper un model avec une clause where
    Par elievar dans le forum Langage SQL
    Réponses: 3
    Dernier message: 16/03/2005, 17h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo