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

Administration et Installation Discussion :

Itération entre table SAS et proc sql


Sujet :

Administration et Installation

  1. #1
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut Itération entre table SAS et proc sql
    Je souhaite lire une table SAS et, pour chaque ligne de la table SAS, aller chercher dans une table tabora d'une base de données ( Oracle par exemple ) la valeur d'un champ relatif à l'identifiant issu de la ligne de la table SAS. Puis mettre à jour le champ ch1 de la table SAS avec la valeur récupérée.

    je vois ce type programme mais est-il faisable ? sinon comment feriez vous ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    data T1;
    set table;
    %prsql(id1,id2); -- id1 et id2 sont l'identifiant dans la table
    ch1 = &val;
    end;
     
    %macro prsql(id1,id2);
    proc sql;
    select colval into :val from tabora where col1=&id1 and col2=&id2;
    run;
    %mend;

  2. #2
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Bonjour,
    Je te propose deux solutions:
    Si la table Oracle n'est pas volumineuse : copier la table Oracle en local est faire une simple jointure avec la table SAS
    Si la table sas n'est pas volumineuse : créer (à partir de la table SAS) une liste avec la clé de le table est ne récupérer de la table Oracle que les élèments souhaités
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    %let sas=('c1','c2','c3'.....);
    proc sql;
    connect oracle...
    create table.... 
    select *
    from table_oracle
    where cle in &sas;
    quit;
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  3. #3
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Sinon tu peux utiliser la proc sql qui marche avec des tables SAS également :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    proc sql;
    	update T1
    	set T1.T1 = (select T2.T2 from T2 where T1.T = T2.T)
    ;
    quit;

  4. #4
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Une table est sur SAS l'autre est sous Oracle.
    Pas possible de faire cette jointure.
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

  5. #5
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    la solution que je propose ne fonctionne pas car je ne peux pas appeler une proc sql dans une étape DATA, même par l'intermédiaire d'une macro.

    La difficulté réside dans le fait qu'il faut lire chaque ligne de la table SAS une par une pour récupérer ensuite une valeur unique dans la table Oracle et mettre à jour ensuite dans la table SAS.

    Impossible de transformer la table Oracle en table SAS car elle fait plusieurs centaines de milliers de lignes

  6. #6
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par bahraoui Voir le message
    Une table est sur SAS l'autre est sous Oracle.
    Pas possible de faire cette jointure.
    Oui, oui, je vois, mais il est toujours possible de faire un libname pour le voir en tant qu'une table SAS. Non ?

  7. #7
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    je ne sais pas si on peut faire en sorte que SAS voit la table Oracle comme une table via un libname. Mais, si c'est possible, ne va-t-on pas charger quand même la table Oracle dans l'environnement SAS car sinon je ne vois pas comment la jointure pourra se faire via le UPDATE.



    j'ai trouvé ceci sur internet pour passer une macro variable d'une étape data vers une proc sql ( via call symput )mais peut-on répéter le même code pour chaque ligne lue dans la table SAS ? dès qu'on sort de l'étape DATA pour executer la proc sql, revient on ensuite dans l'étape DATA pour ligne la ligne suivante ? et comment récupérer ensuite la variable val ?



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    data _null_;
    set tabsas;
    	call symput ('id1', valeur);
    run;
     
    proc sql;
    	select colval into :val from tabora where col1=&id1 ;
     
    quit;

  8. #8
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par marti Voir le message
    je ne sais pas si on peut faire en sorte que SAS voit la table Oracle comme une table via un libname. Mais, si c'est possible, ne va-t-on pas charger quand même la table Oracle dans l'environnement SAS car sinon je ne vois pas comment la jointure pourra se faire via le UPDATE.
    Je ne sais pas comment ça marche, mais on a plusieurs bibliothèques oracle et plusieurs bibliothèques de SAS. Et on fait des jointures.

    Citation Envoyé par marti Voir le message
    j'ai trouvé ceci sur internet pour passer une macro variable d'une étape data vers une proc sql ( via call symput )mais peut-on répéter le même code pour chaque ligne lue dans la table SAS ? dès qu'on sort de l'étape DATA pour executer la proc sql, revient on ensuite dans l'étape DATA pour ligne la ligne suivante ? et comment récupérer ensuite la variable val ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    data _null_;
    set tabsas;
    	call symput ('id1', valeur);
    run;
     
    proc sql;
    	select colval into :val from tabora where col1=&id1 ;
     
    quit;
    Ça ressemble à la jointure avec un index. C'est à dire pour chaque ligne de la table T1 on fait une "requête" (entre parenthèses parce que ce n'est pas une requête SQL) sur la table T2 un utilisant l'index créé sur le champs de jointure. Le syntaxe est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    data RESULTAT;
        set T1;
        set T2 key = T;
        T11 = T21;
    run;
    Pour une table T1 avec les champs T et T11, une table T2 avec deux champs T et T21 et une index créé sur le champs T.
    Attention au comportement un peu bizarre du SAS s'il trouve pas de correspondance dans la table T2. Dans ce cas SAS garde la valeur qu'il a trouvé pour la ligne précédente, mais met un top dans une variable système _IORC_. A vous de voir ce qu'il faut faire dans ce cas.

  9. #9
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    et le fait que l'on fasse des jointures entre une table SAS et une table Oracle volumineuses ne va pas coinçer d'après ton experience?

    admettons que cela marche, je souhaite faire ceci exactement : je souhaite remplir les champs for1 à for5 de ma table SAS T1 à partir du champ for de ma table Oracle T2 ( le champ noi de T2 contient les valeurs de 1 à 5 correspondant en fait à for1 à for5 dans T1 ). J'utilise la macro suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    %macro m1(nb);
      %do i=1 %to &nb;
        proc sql;
          update t1 set t1.for&i = (select t2.for from t2 where t2.noa=t1.noa and t2.nol=t1.nol and noi="&i");
        end;
       %end;
    %mend;
     
    %m1(5);
    exemple :

    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
     
    en entrée :
    Table T1
     
    noa  nol  for1  for2  for3  for4  for5
    A     A         
    B     B
     
    Table T2
     
    noa  nol  noi  for
    A     A     1    f1         
    A     A     2    f2
    A     A     3    f3
    A     B     1    f4
    A     B     3    f5
     
    et en sortie :
     
    Table T1
     
    noa  nol  for1  for2  for3  for4  for5
    A     A     f1   f2    f3         
    B     B     f4         f5
    je crains que cela bloque quand noa = A, nol = A et noi = 4 car cet enregistrement n'existe pas dans T2 et donc le Select ne renvoit rien. D'abord est ce que la macro va s'arrêter à cet endroit et, si oui, comment faire pour que la macro continue de s'executer ?

  10. #10
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par marti Voir le message
    et le fait que l'on fasse des jointures entre une table SAS et une table Oracle volumineuses ne va pas coinçer d'après ton experience?
    Je n'ai jamais eu des tables plus de 1.000.000 enregistrements, pour le moment ça va. Et je suis nouveau dans SAS, j'ai pas encore fait d'optimisation. Pour l'instant le principal c'est que ça marche :-)

    Sinon ton code doit marcher parfaitement, j'ai juste corrigé quelques coquilles :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    %macro m1(nb);
      %do i=1 %to &nb;
        proc sql;
          update t1 set for&i. = (select t2.for from t2 where t2.noa=t1.noa and t2.nol=t1.nol and noi="&i.");
        quit;
       %end;
    %mend;
     
    %m1(5);
    Tu as raison, quand noa = A, nol = A et noi = 4 car cet enregistrement n'existe pas dans T2 et donc le Select ne renvoie rien (ou plutôt null, "."). Par contre ceci na fait pas bloquer la macro, elle met à jour la cellule correspondante (avec null) et continue avec l'itération suivante de la boucle.

  11. #11
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    Merci

    je suis plutôt rassuré sur la taille de mes tables ( plusieurs centaines de milliers de lignes)
    Je vas mettre en pratique maintenant...

  12. #12
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    ok ça marche..encore un ch'ti problème :

    Si je rajoute dans T2 une ligne identique à la première ligne ( cf ligne en gras ), la macro ne fonctionne plus car pour cette ligne je demande de mettre à jour dans T1 la colonne for1 avec 2 valeurs qui sont identiques. Comment forcer à mettre dans T1 la valeur f1 dans for1 à la ligne noa=A, nol=A ?

    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
    
    TABLE T2
     
    noa  nol  noi  FOR
    A     A     1    f1   
    A     A     1    f1               
    A     A     2    f2
    A     A     3    f3
    A     B     1    f4
    A     B     3    f5
     
    et en sortie :
     
    TABLE T1
     
    noa  nol  for1  for2  for3  for4  for5
    A     A     f1   f2    f3         
    B     B     f4         f5

  13. #13
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par marti Voir le message
    ok ça marche..encore un ch'ti problème :

    Si je rajoute dans T2 une ligne identique à la première ligne ( cf ligne en gras ), la macro ne fonctionne plus car pour cette ligne je demande de mettre à jour dans T1 la colonne for1 avec 2 valeurs qui sont identiques. Comment forcer à mettre dans T1 la valeur f1 dans for1 à la ligne noa=A, nol=A ?
    1. Si les lignes avec les mêmes valeurs de la clé noa-nol-,oi sont complétement identiques, tu peux mettre le mot-clé "distinct" juste derrière la "select". Ça fait de sorte que la requête ne retourne que des lignes différentes, dans ce cas - une seule ligne.
    2. Si les lignes avec la même clé ne sont pas toujours différentes ("A A 1 f1" et "A A 1 f2"), tu doit d'abord définir ce que tu veut faire dans ce cas et prendre la fonction d'agrégation appropriée (min, max, mean, first, etc.)

  14. #14
    Membre du Club
    Inscrit en
    Avril 2005
    Messages
    175
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 175
    Points : 59
    Points
    59
    Par défaut
    ok merci pour la reponse

    encore un ch'ti problème : je veux remplacer 1,2,3 par 01,02,03 et donc noi = 01 ou 02 ou 03 ainsi que for01, for02, for03, for04, for05 comment faire ?

  15. #15
    Membre actif

    Profil pro
    Inscrit en
    Avril 2008
    Messages
    233
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 233
    Points : 254
    Points
    254
    Par défaut
    Citation Envoyé par marti Voir le message
    ok merci pour la reponse

    encore un ch'ti problème : je veux remplacer 1,2,3 par 01,02,03 et donc noi = 01 ou 02 ou 03 ainsi que for01, for02, for03, for04, for05 comment faire ?
    Tu peux avoir plus de 9 for ? Ou tu t'arrête avant for10 ? Si c'est le cas, remplace UPDATE dans le code par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UPDATE t1 SET for0&i. = (SELECT t2.FOR FROM t2 WHERE t2.noa=t1.noa AND t2.nol=t1.nol AND noi="&i.");
    Sinon, il faut voir le format, et moi, je ne suis pas super fort en formats SAS...

  16. #16
    Membre habitué
    Homme Profil pro
    Inscrit en
    Juin 2006
    Messages
    101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations forums :
    Inscription : Juin 2006
    Messages : 101
    Points : 187
    Points
    187
    Par défaut
    Pour formater une valeur avec zero non significatif utiliser la cde suivante :

    DATA ..... ;
    Format var1 Z2. ; /* ex : 05 */
    Format var2 Z3. ; /* ex : 005 */
    Format var3 Z8.2 ; /* ex : 00123.54 */

    .....


    Pour plus explications voir :
    http://thesasreference.wordpress.com...type_variable/

  17. #17
    Membre émérite

    Homme Profil pro
    Consultant en Business Intelligence
    Inscrit en
    Mars 2005
    Messages
    1 364
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 364
    Points : 2 329
    Points
    2 329
    Par défaut
    Citation Envoyé par green_fr Voir le message
    Oui, oui, je vois, mais il est toujours possible de faire un libname pour le voir en tant qu'une table SAS. Non ?
    Effectivement c'est possible de faire un libname, ce qui facilite le code, mais les preformances ne sont pas terrible.
    De préfèrence utiliser du SQL path-trought, pour consulter de grosses bases.
    Consultez les FAQs et les anciens postes avant de poser vos questions. Merci

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

Discussions similaires

  1. Choix entre requête SQL ou mapping entre tables
    Par webfranc dans le forum Connectivité
    Réponses: 4
    Dernier message: 25/01/2011, 14h52
  2. Réponses: 2
    Dernier message: 17/05/2010, 13h29
  3. Proc export d'une table SAS dans un répertoire
    Par r_dani dans le forum SAS Base
    Réponses: 1
    Dernier message: 04/11/2008, 12h34
  4. Réponses: 5
    Dernier message: 12/09/2008, 16h30
  5. proc upload table sas de windows vers mvs
    Par marti dans le forum Administration et Installation
    Réponses: 0
    Dernier message: 02/07/2008, 21h04

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