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

Débutez Discussion :

Concatener une colonne en une chaine


Sujet :

Débutez

  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 11
    Points : 10
    Points
    10
    Par défaut Concatener une colonne en une chaine
    Bonjour,

    Je cherche à concaténer le contenu d'une colonne dans une macro variable.

    Une colonne de ma table contient des codes postaux (5 caractères) un code postal par ligne, résultat d'une opération compliquée.
    L'objectif regrouper toutes les valeurs (normalement moins d'une centaine mais le nombre est variable) en une seule chaine. Exemple en dessous.

    CodePostal
    75115
    75116
    69001
    2A100

    et le transformer en une seule MaChaine = '75115','75116','69001','2A100' une concaténation avec les séparateurs qui vont bien.

    L'objectif est ensuite de passer la chaine en paramètre répétitif à des requêtes, et éviter de traiter comme un IN (SELECT ...) y compris dans des fonctions de type IF pour du recodage et améliorer le temps de réponse (un pb d'un vrai big data).

    J'ai tourné autour DATA avec RETAIN mais je dois m'y prendre mal ou c'est complètement inadapté pour des chaines. Un PIVOT de type TRANSPOSE semble pas adapté.
    Et aucune idée de comment faire une boucle qui lit chaque ligne ... Bref je tourne en rond.

    Merci pour la guidance vers un début de solution.

    PS : je débute la partie programme sur SAS Enterprise Guide ayant besoin d'enchainer des requêtes complexes, tout en étant très autonome dans nombre de dialecte de SQL et langages de programmation

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 11
    Points : 10
    Points
    10
    Par défaut Une réponse à concaténer une colonne dans une chaîne
    Je me réponds à moi-même.

    En fait la solution était bien avec un RETAIN mais mon problème provenait d'un problème de taille de la chaine de caractère.
    Les déclarations en SAS sont pas très clair et pas plus pour les macro variable. En particulier lors de mes premiers essais, la longueur de chaine n'était pas suffisante pour accumuler.

    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
    data temp;
     LENGTH  ListeCP $32767; 
        /* logiquement je n'aurais pas du avoir besoin de déclarer une colonne, et accumuler ma liste dans une variable */
        set SelectTerritoire;
     retain ListeCP ;
     If first.Code_CP then ListeCP="'"; 
        /* initialisation de la liste avec une apostrophe qui à l'évidence au vu des résultats ne fonctionne pas, d'ailleurs une version avec last.Code_CP pour ajouter l'apostrophe fermante à la fin n'est pas mieux. Tant pis le PROC SQL suivant le fera */
        ListeCP = CATX("','",ListeCP,Code_CP);
     RUN; 
    
    PROC SQL; 
        %Global ListeCodePostal;
        /* Pas élégant mais les fonctions de concaténation ont des résultats aléatoires, CAT ne produit rien (la chaine est vide) ou alors la syntaxe n'est pas celle du manuel, alors que CATS fait ce qu'on attend : une concaténation. 
            Pire l'opérateur de  concaténation || fonctionne pour la 1e apostrophe mais pas pour la dernière ... En sus la fonction Max ne peut être incluse dans la concaténation, qu'à cela ne tienne un SELECT imbriqué pour obtenir le résultat.    
       */
        SELECT CATS("'",t1.ListeCP1,"'") INTO :ListeCodePostal FROM (SELECT Max(ListeCP) AS ListeCP1 FROM temp) AS t1;
        /* contrairement à d'autres SQL plus usuel on ne peut affecter un Select ... à une macro variable. Tant pis, ListeCodePostal contient le résultat, on va s'en contenter.
           Un peu trop pressé par le reste du travail à faire pour  explorer mieux les limites de ce langage, déroutant toutefois par  rapport à du PL/SQL voir même du mySQL. */
    RUN; 
    
    Sans doute très moche comme façon de résoudre ma question mais d'une part cela fonctionne, et d'autre part le langage de SAS est assez déroutant avec des effets de bords peu compréhensibles en première approche. Et le guide en ligne SAS n'est pas réellement didactique même pour la syntaxe des fonctions.

  3. #3
    Membre éprouvé
    Homme Profil pro
    Statisticien/développeur BI
    Inscrit en
    Janvier 2012
    Messages
    326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Statisticien/développeur BI
    Secteur : Transports

    Informations forums :
    Inscription : Janvier 2012
    Messages : 326
    Points : 1 142
    Points
    1 142
    Par défaut
    Bonjour,

    Ci-dessous une solution en une simple étape data :

    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
    data toto;
    input CodePostal $5.;
    cards;
    75115
    75116
    69001
    2A100
    ;
    run;
     
    data _null_;
    set toto end=fin;
    if _n_ = 1 then call symput('ListeCP',"'"||CodePostal);
    else call symput('ListeCP',symget('ListeCP')||"','"||CodePostal);
    if fin then call symput('ListeCP',symget('ListeCP')||"'");
    run;
     
    %put ListeCP = &ListeCP;

  4. #4
    Membre expérimenté
    Homme Profil pro
    Développeur en SAS/ Statisticien
    Inscrit en
    Janvier 2013
    Messages
    483
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur en SAS/ Statisticien
    Secteur : Enseignement

    Informations forums :
    Inscription : Janvier 2013
    Messages : 483
    Points : 1 552
    Points
    1 552
    Par défaut
    Bonjour,
    Un seul code en SQL avec la fonction Quote :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Proc SQL noprint;
    select quote(strip(name)) 
    into : listVar separated by ', ' 
    from sashelp.class ;
    quit ;  %put &listVar ;
    NB: La longueur de la Macro Variable dépond de la version de SAS : 200 caractères en v6, 32000 en v8, 65000 en v9 .......

    Cordialement Ward

  5. #5
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Décembre 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vendée (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    Citation Envoyé par hossward Voir le message
    Bonjour,
    Un seul code en SQL avec la fonction Quote :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Proc SQL noprint;
    select quote(strip(name)) 
    into : listVar separated by ', ' 
    from sashelp.class ;
    quit ;  %put &listVar ;
    NB: La longueur de la Macro Variable dépond de la version de SAS : 200 caractères en v6, 32000 en v8, 65000 en v9 .......

    Cordialement Ward
    Un grand merci. j'étais arrivé à peu près à la même solution mais lentement et par tâtonnements. Pour l'autre réponse suis en 9.2 sauf erreur

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

Discussions similaires

  1. Concatener une chaine de caractère avec un count
    Par huître dans le forum SAS Base
    Réponses: 6
    Dernier message: 14/05/2012, 14h48
  2. Executer une chaine concatener dans une procedure stockée
    Par nic413 dans le forum SQL Procédural
    Réponses: 6
    Dernier message: 19/06/2006, 11h24
  3. [VB6] Former et concatener une chaine
    Par Sophie2097 dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 05/04/2006, 16h31
  4. [debutant] Concatenation d'une chaine (string) et d'entiers
    Par websurfeur dans le forum Débuter
    Réponses: 2
    Dernier message: 26/03/2006, 12h05
  5. [Oracle 8i/ Sql] Concatener une chaine
    Par dimdidi dans le forum Oracle
    Réponses: 5
    Dernier message: 07/02/2006, 14h42

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