1. #1
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2011
    Messages : 247
    Points : 86
    Points
    86

    Par défaut Jointure via HASH table

    Bonjour à toutes et à tous

    Après moult recherches dns les tutoriels et les anciennes discusions, je n'ai pas trouver de solutions
    à mon problème. je viens solliciter votre aide.
    Bien entendu tout lien vers une sucseptible de m'aider serait labienvenue


    Je dispose de trois tables "Team_Player" , "Team_Sponsor" et "Infos_Club" que je souhaite fusionner (par Hash table que je découvre). La table attendue
    en sortie doit contenir tous les champs de "Team_Player" , 3 champs "Team_Sponsor" et 3 champs "Infos_Club".
    Ma clé de jointure est se nomme : Id_Player dans "Team_Player"
    Joueur_CD dans "Team_Sponsor"
    Id_Joueur dans "Infos_Club"

    Le code que j'utilise pour ce faire est le suivant :

    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
     
    data Table_last ;
    /*Les 3 champs de "Team_Sponsor" */
    attrib Numero length=$3.  ;
    atrrib Equipementier length=$12. ;
    attrib DT_Contrat length = 5 format = ddmmyy10. ;
     
    /*Les 3 champs de "Infos_Club"*/
    attrib Effectif length=$3.  ;
    atrrib Ville  length=$12. ;
    attrib DT_Creation length = 5 format = ddmmyy10. ;
     
     
    set WORK.Team_Player ;
     
    if _n_ = 1 then do ;
          declare hash h_Spon(dataset:"WORK.TEAM_SPONSOR");
          h_Spon.defineKey("Joueur_CD") ;
          h_Spon.defineData("Numero","Equipementier","DT_Contrat") ;
          h_Spon.defineDone();
     
          declare hash h_Club(dataset:"WORK.Infos_Club");
          h_Club.defineKey("Id_Joueur") ;
          h_Club.defineData("Effectif","Ville","DT_Creation") ;
          h_Club.defineDone();
     
          IF (h_Spon.FIND(KEY: Joueur_CD) = 0 )
          and (h_Club.FIND (KEY:Id_Joueur )= 0) THEN OUTPUT;
    end ;
     
    run;
    Ma fusion ne se fait car j'ai le message d'erreur suivant : "Type mismatch for data variable Numero ... " idem pour les champ "Equipementier", "DT_Contrat","Effectif","Ville" et "DT_Creation" .


    Pour plus de compréhension, vous trouverez en pj (sur les 3 premières feuilles ) la structure des tables que je dois fusionner.

    Je vous remercie par avance de votre aide

    Kedmard.
    Fichiers attachés Fichiers attachés

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2011
    Messages : 247
    Points : 86
    Points
    86

    Par défaut

    Hello ,

    Personne n'aurait ne serait-ce qu'un embriyon de piste ??

    Merci d'avance

  3. #3
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    mai 2011
    Messages
    675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2011
    Messages : 675
    Points : 1 562
    Points
    1 562

    Par défaut

    Bonsoir, j'ai vu tes données sous Excel, après je ne connais pas la structure exacte de tes tables SAS (une proc content sur chaque table aurait été un plus !).

    Est-ce que ce code fonctionnerait-il correctement ? (code non testé!)

    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
    
    data Table_last ;
    
    /*Les 3 champs de "Team_Sponsor" */
          IF 0 then set Team_Sponsor;
    
    /*Les 3 champs de "Infos_Club"*/
          IF 0 then set Infos_club ;
    
    set WORK.Team_Player ;
     
    if _n_ = 1 then do ;
          declare hash h_Spon(dataset:"WORK.TEAM_SPONSOR");
          h_Spon.defineKey("Joueur_CD") ;
          h_Spon.defineData("Numero","Equipementier","DT_Contrat") ;
          h_Spon.defineDone();
     
          declare hash h_Club(dataset:"WORK.Infos_Club");
          h_Club.defineKey("Id_Joueur") ;
          h_Club.defineData("Effectif","Ville","DT_Creation") ;
          h_Club.defineDone();
     
    
    end ;
     
    RC_h_Spon=h_Spon.FIND(KEY:Id_Player);
    RC_h_Club=h_Club.FIND(KEY:Id_Player);
    DROP RC_h_: ;
    
    IF RC_h_Spon=0 and RC_h_Club=0 THEN OUTPUT ; /*** -> le joueur est en sortie seulement si il est dans les deux hash ***/
    
    run;
    La syntaxe est davantage différente que ne devrait nécessité la simple bonne execution du code, mais c'est ainsi que j'ai l'habitude de coder.
    Par contre le test avec les find() doit absolument se trouver en dehors de la phase d"initialisation (if _n_=1 then do;end; ) car justement c'est une phase d'initialisation des tableaux associatifs alors que tu veux balayer ta table (Team_Player) avec l'itérateur SAS habituel (ne t'inquiète on l'a tous fait ou presque au début...)


    Cordialement

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2011
    Messages : 247
    Points : 86
    Points
    86

    Par défaut

    Bonjour JeromeMATHIAS,

    Grand merci pour l'intérêt que tu portes à mon problème.
    Ton code marche très bien et il m'a permi de me rendre compte que je n'ai pas correctement spécifié ma demande.

    En fait ce que je veux ce n'est pas seulement d'avoir en sortie les joueurs présents dans les 3 tables mais
    tous les joueurs de la table à balayer c-à-d Team_Player avec des valeurs manquantes si possibles sur les champs propres aux deux autres tables .

    En résumé je veux en sortie le résultat de :

    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
     
    proc sql;
    create table Table_last as 
    select t1.*, t2.Numero ,
                 t2.Equipementier,
                 t2.DT_Contrat ,
    			 t3.Effectif,
                 t3.Ville,
                 t3.DT_Creation
    from Team_Player as t1
    left join TEAM_SPONSOR as t2
    on (t1.Id_Player=t2.Joueur_CD)
    left join Infos_Club  as t3
    on (t1.Id_Player=t3.Id_Joueur) ;
    quit;

    J'ai essayé de mettre un OR comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    IF (RC_h_Spon = 0 OR RC_h_Club = 0) THEN

    mais ça n'a pas produit l'effet escompté


    Aurais-tu une idée ?

    En te remerciant une fois de plus.

    Kedmard

  5. #5
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    mai 2011
    Messages
    675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2011
    Messages : 675
    Points : 1 562
    Points
    1 562

    Par défaut

    voici alors

    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
    data Table_last ;
    
    /*Les 3 champs de "Team_Sponsor" */
          IF 0 then set Team_Sponsor;
    
    /*Les 3 champs de "Infos_Club"*/
          IF 0 then set Infos_club ;
    
    set WORK.Team_Player ;
     
    if _n_ = 1 then do ;      declare hash h_Spon(dataset:"WORK.TEAM_SPONSOR");
          h_Spon.defineKey("Joueur_CD") ;
          h_Spon.defineData("Numero","Equipementier","DT_Contrat") ;
          h_Spon.defineDone();
     
          declare hash h_Club(dataset:"WORK.Infos_Club");
          h_Club.defineKey("Id_Joueur") ;
          h_Club.defineData("Effectif","Ville","DT_Creation") ;
          h_Club.defineDone();
     
    
    end ;
     
    RC_h_Spon=h_Spon.FIND(KEY:Id_Player);
    RC_h_Club=h_Club.FIND(KEY:Id_Player);
    DROP RC_h_: ;
    
    /*IF RC_h_Spon=0 and RC_h_Club=0 THEN OUTPUT ;*/
    
    run;
    Cordialement

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2011
    Messages : 247
    Points : 86
    Points
    86

    Par défaut

    Bonjour JeromeMATHIAS

    Avec ton nouveau code j'ai le nombre de lignes attendues en sortie, il se pose en revanche un
    problème sur les champs censés être manquant, je constate qu'ils prennent la valeur de la ligne
    la ligne précédente.

    Tu trouveras ci-dessous deux images correspondant aux résultats obtenus d'une part avec ton code et d'autre
    part avec la proc sql (résultat souhaité).

    --Avec HASH
    Nom : Resultat_HASH.JPG
Affichages : 47
Taille : 42,7 Ko

    --Avec la proc sql
    Nom : Resultat_SQL.JPG
Affichages : 47
Taille : 38,7 Ko


    Je continue de chercher . On se rapproche tout de même de la solution.

    Merci .

    Cordialement,

  7. #7
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    mai 2011
    Messages
    675
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : mai 2011
    Messages : 675
    Points : 1 562
    Points
    1 562

    Par défaut

    Bonjour,

    alors effectivement c'est que je n'ai pas l'habitude de faire du hash pour ce genre de fusion (en fait je n'utilise jamais de hash pour faire ce que la SQL sait très bien faire ).
    Le problème vient des lignes "if 0 then set table ;" au début du code qui sont responsables de retain automatiques....

    Remplace les deux if 0 par les attrib du début et tout devrait rentrer dans l'ordre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    attrib Numero length=$3.  ;
    atrrib Equipementier length=$12. ;
    attrib DT_Contrat length = 5 format = ddmmyy10. ;
     
    /*Les 3 champs de "Infos_Club"*/
    attrib Effectif length=$3.  ;
    atrrib Ville  length=$12. ;
    attrib DT_Creation length = 5 format = ddmmyy10. ;
    Je n'avais jamais remarqué cet effet avant ton problème...

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2011
    Messages : 247
    Points : 86
    Points
    86

    Par défaut

    Finalement avec le code ci-dessous j'ai la table souhaitée .

    Il faut toutefois veiller à ce que les longueurs des clés de jointures sur les tables "secondaires" soient identiques et >= à celle de la table à balayer.
    Autrement dit

    length(Joueur_CD)= length(Id_Joueur) et >=length(Id_player)



    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
     
    data Table_last ;
    set WORK.Team_Player ;
     
    /*Les champs utiles de "Team_Sponsor" */
        attrib Numero	     length=8    format=best12.  ;
        attrib Equipementier length=$9.  format=$9. ;
        attrib DT_Contrat    length = 5  format = ddmmyy10. ;
        attrib Joueur_CD     length=$8.  format=$8. ;
    /*Les champs utiles de "Infos_Club"*/
        attrib Effectif     length=8     format=best12.  ;
        attrib Ville	    length=$12.  format=$12.;
        attrib DT_Creation	length =8    format=best12. ;
        attrib Id_Joueur    length=$8.   format=$8.;
     
     
    if _n_ = 1 then do ;      
          declare hash h_Spon(dataset:"WORK.TEAM_SPONSOR");
          h_Spon.defineKey("Joueur_CD") ;
          h_Spon.defineData("Numero","Equipementier","DT_Contrat") ;
          h_Spon.defineDone();
     
          declare hash h_Club(dataset:"WORK.Infos_Club");
          h_Club.defineKey("Id_Joueur") ;
          h_Club.defineData("Effectif","Ville","DT_Creation") ;
          h_Club.defineDone();
     
     
    end ;
     
    RC_h_Spon=h_Spon.FIND(KEY:Id_Player);
    RC_h_Club=h_Club.FIND(KEY:Id_Player);
    DROP RC_h_: ;
    DROP Joueur_CD  Id_Joueur ; 
    run;
    Merci encore JeromeMATHIAS

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

Discussions similaires

  1. [2008R2] Jointure entre deux tables via des colonnes XML
    Par BILL33 dans le forum Développement
    Réponses: 7
    Dernier message: 18/11/2016, 00h27
  2. Jointure via table avec clés composées
    Par pasqua80000 dans le forum Débuter
    Réponses: 1
    Dernier message: 01/07/2015, 22h22
  3. Chercher une donnée via une table intermédiaire et multi jointure
    Par Vincent Valentine dans le forum Requêtes
    Réponses: 6
    Dernier message: 05/02/2015, 09h53
  4. Jointure entre trois tables via SQL Developer
    Par mam51100 dans le forum Oracle
    Réponses: 4
    Dernier message: 25/01/2014, 10h20
  5. Jointure sur 2 tables de bases différentes
    Par Celina dans le forum Langage SQL
    Réponses: 10
    Dernier message: 10/11/2003, 11h56

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