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 :

Somme en ligne sur un nombre variable de colonnes [SQL]


Sujet :

SAS Base

  1. #1
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut Somme en ligne sur un nombre variable de colonnes
    Bonjour,

    Je n'ai pas réussi à trouver le même problème donc je le poste ici :
    J'ai une table qui est transposée avec en colonnes des variables commençant par "used_". En faisant le proc transpose avant, j'obtiens un nombre de colonnes variable selon ma table de départ, ça peut aller de 3 à plus de 20.

    Ma deuxième étape consiste à faire une somme pour chaque ligne de ses colonnes. J'ai donc écrit une proc sql (car je fais une fusion en même temps):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    PROC SQL; 
        CREATE TABLE Pref_utilization3 (drop= TL2) AS
        SELECT a.*, sum(used_MFN_zero, used_MFN_dutiable, used_GSP, used_LDC, used_J47, used_J91) as import_value,
               b.cat
        FROM Pref_utilization2 AS a
        LEFT JOIN cat_secteur AS b ON a.TL2 = b.HS6;
    QUIT;
    Mais pour ne pas avoir à changer le nom used_... à chaque fois que je lance le programme pour une nouvelle table, je me demandais si je pouvais écrire un programme en utilisant sum(like 'used_%') mais ça me marque une erreur de syntaxe.

    Sinon j'ai pensé à faire une boucle du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    %let pref1=GSP;
    %let pref2=J47;
    %let pref3=LDC;
    %let pref4=J91;
     
    DATA ESSAI;
    SET Pref_utilization2;
    DO i=1 to 4; *mais le nombre de variable peut changer;
    tot=sum(&&used_pref&i.); end;
    RUN;
    Le programme est faux bien sûr... et il ne permet pas d'automatiser le processus car le nombre de variables est fixé à 4.
    Merci pour vos réponses.

  2. #2
    Membre régulier
    Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Septembre 2013
    Messages
    27
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Consultant en Business Intelligence

    Informations forums :
    Inscription : Septembre 2013
    Messages : 27
    Points : 76
    Points
    76
    Par défaut
    Il faut utiliser un array dans ce cas la.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    DATA ESSAI;
    SET Pref_utilization2;
    SUM=0;
    ARRAY USED{*} USED_:;
    do i=lbound(USED) to hbound(USED);
        sum=sum+used(i);
    end;
    RUN;

  3. #3
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Merci pour votre réponse, j'ai testé et la nouvelle table apparaît avec 2 nouvelles variables :
    - SUM qui est égale à 0 partout
    - i qui est égale à 6 partout
    je ne sais pas si c'est le fait que Used_: ne soit pas pris en compte...

  4. #4
    Membre éclairé

    Femme Profil pro
    SAS FRANCE - Support Clients France et Europe
    Inscrit en
    Février 2010
    Messages
    289
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : SAS FRANCE - Support Clients France et Europe
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 289
    Points : 886
    Points
    886
    Par défaut
    Bonjour,

    Le programme de Emrall333 a juste besoin d'une petite modification. il faut utiliser DIM à la place de lbound et hbound pour avoir la taille de l'array. Et faire un drop de i pour ne pas avoir la valeur de la boucle en sortie.
    L'array va justement permettre de gérer le nombre changeant de variables.

    Cordialement,
    Géraldine Cade Deschamps
    Support Clients SAS

  5. #5
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 625
    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 625
    Points : 3 403
    Points
    3 403
    Par défaut
    Hello,
    Si j'ai bien compris ton problème, tu veux sommer uniquement les variables commençant par USED_, si c'est ce que tu recherches, je te propose cette solution :

    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
     
     
    data exemple;
    input used_1-used_5 var;
    cards;
    1 3 3 3 3 9
    3 4 3 5 6 8
    5 5 6 . . 6
    4 5 . . . 6
    ;
    run;
     
    data exemple1;
    set exemple;
    somme=sum (of used_:);
    run;
    Ici, je demande à SAS de calculer la somme des variables ayant comme préfix USED_ , les deux points ( colon) représentent un joker.

  6. #6
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Bonjour,

    merci pour vos réponses complémentaires. Une fois de plus l'array n'a pas fonctionné avec l'alternative DIM en lieu de lbound / hbound, car cette fois-ci la somme reprend uniquement la dernière colonne nommée "used_" et non l'ensemble des colonnes.

    La solution de SAM a parfaitement fonctionné, merci. Mais ce que je me demandais c'est pourquoi la même formule dans la proc sql ne fonctionne pas.
    Ca me marque une erreur :
    ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, (, ), *, **, +, ',', -,
    '.', /, <, <=, <>, =, >, >=, ?, AND, BETWEEN, CONTAINS, EQ, EQT, GE, GET, GT, GTT,
    IN, IS, LE, LET, LIKE, LT, LTT, NE, NET, NOT, NOTIN, OR, ^, ^=, |, ||, ~, ~=.

    Je souhaiterais avoir vos commentaires mais je vais placer la discussion en résolue

  7. #7
    Modérateur

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Février 2011
    Messages
    1 625
    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 625
    Points : 3 403
    Points
    3 403
    Par défaut
    à mes connaissances, en SQL le OF ne fonctionne pas , tu peux néanmoins faire la somme de tes colonnes en SQL mais à condition de taper toutes les colonnes à la main, Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
     
    proc sql;
    create table exemple2 as select *, sum ( used_1,used_2,used_3,used_4, used_5) as somme 
    from exemple;
    quit;
    ou sinon si tu veux absolument passer par une proc sql voici une solution un peu longue en utilisant le langage macro :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    proc contents data= exemple out= var (keep =NAME where=(upcase(NAME) =: 'USED_')) noprint ; 
    run;
     
    proc sql noprint;
    select name into: mv_name separated by ',' from var;
    quit;
     
    proc sql;
    create table exemple2 as select *, sum ( &mv_name) as somme 
    from exemple;
    quit;
    ou sinon :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
    proc sql noprint;
    select distinct name into: mv_name separated by ',' from dictionary.columns /*sashelp.vcolumn*/where upcase(libname)='WORK' and upcase(memname)='EXEMPLE' and upcase(name) like 'USED_%';
    quit;
     
     
     
    proc sql;
    create table exemple2 as select *, sum ( &mv_name) as somme 
    from exemple;
    quit;

  8. #8
    Membre à l'essai
    Femme Profil pro
    Inscrit en
    Juin 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Juin 2012
    Messages : 25
    Points : 14
    Points
    14
    Par défaut
    Merci SAM, c'est parfait!

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

Discussions similaires

  1. Insérer des lignes copiées en nombre variable
    Par bomimi dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 25/01/2015, 11h03
  2. [MySQL] Somme de lignes sur un champ
    Par aiss57 dans le forum PHP & Base de données
    Réponses: 8
    Dernier message: 04/05/2009, 22h23
  3. Réponses: 7
    Dernier message: 08/01/2008, 19h43
  4. Réponses: 8
    Dernier message: 14/11/2007, 10h27
  5. Somme de lignes sur union : je sèche.
    Par Vincenteyssier dans le forum Langage SQL
    Réponses: 4
    Dernier message: 27/12/2005, 10h15

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