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

Langage SQL Discussion :

Problème de jointure externe


Sujet :

Langage SQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut Problème de jointure externe
    Bonjour

    Je ne comprends pas pourquoi ma jointure externe ne retour pas les résultats escomptés.

    Ma table ETAPES_PROJETS contient les champs
    "code_projet" (not null) , "etape_projet" (not null), "detail_etape_projet" (null possible)

    et ma table ACTIVITE contient les memes champs + "jour" et "temps".

    Je souhaite lister toutes les etapes_projets (qu'elles aient un "detail_etape_projet" ou pas et avoir pour chacune le total du temps passé dessus.

    si je fais cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT   e.code_etape,e.detail_etape, sum(a.temps) "Temps réel" 
        FROM etapes_projets e, activite a 
       WHERE e.code_projet = 'STATSFREQ' 
         AND a.code_projet(+) = e.code_projet 
         AND a.code_etape_projet(+) = e.code_etape 
    	 AND a.detail_etape_projet(+) = e.detail_etape 
    GROUP BY e.code_etape,e.detail_etape
    J'obtiens la liste de toutes les etapes mais je n'ai les totaux que pour les etapes ou les 3 champs sont renseignés et je n'ai pas de totaux pour les étapes ou "detail_etape" est vide.

    Merci d'avance à vous
    Loko

  2. #2
    Membre averti Avatar de bouvda
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 252
    Points : 318
    Points
    318
    Par défaut
    Bonjour,

    cette requête produit-elle ce que vous voulez ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT   e.code_etape,e.detail_etape, sum(a.temps) "Temps réel" 
        FROM etapes_projets e LEFT OUTER JOIN activite a 
        ON e.code_projet = a.code_projet 
         AND e.code_etape_projet = a.code_etape 
         AND e.detail_etape_projet = a.detail_etape 
       WHERE e.code_projet = 'STATSFREQ' 
    GROUP BY e.code_etape,e.detail_etape

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut
    Bonjour

    non, j'avais déja essayé avec la syntaxe SQL2 mais le résultat est identique.

  4. #4
    Membre averti Avatar de bouvda
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 252
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par Loko
    Bonjour

    non, j'avais déja essayé avec la syntaxe SQL2 mais le résultat est identique.
    Quand vous dites que vous n'avez pas les totaux, en fait vous avez bien les lignes mais les totaux sont vides ?
    Si c'est le cas c'est normal car vous sommez des valeurs NULL ce qui donne des valeurs NULL en résultat.
    Si vous voulez obtenir 0 par exemple alors dans votre requête il faut faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sum(coalesce(a.temps,0))

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut
    je viens d'essayer coalesce. Désormais j'ai des 0 partout là ou les totaux étaient vides.

    Cependant certains totaux ne sont pas bons. Parmi les lignes de "ETAPES_PROJETS" qui n'ont pas de valeur dans le champ "etape_projet" certaines n'ont effectivement aucune équivalence dans la table ACVTIVITE donc le total 0 ou null est correct, par contre d'autres ont bel et bien des correspondance avec la table ACTIVITE et pour celles-là il devrait y avoir un total >0.

    Donc en résumé le bon total n'apparait que si les 3 champs sont remplis et pas si detail_etape est null dans les 2 tables.

    Pour mieux comprendre peut etre, un exemple avec donnnées :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ETAPES_PROJETS
    CODE_PROJET  CODE_ETAPE DETAIL_ETAPE
    STATSFREQ     ANA              
    STATSFREQ     DEV             ETAPE1
    STATSFREQ     DEV             ETAPE2
    
    ACTIVITE
    CODE_PROJET CODE_ETAPE DETAIL_ETAPE_PROJET TEMPS
    STATSFREQ    ANA                                             1
    STATSFREQ    ANA                                             0.5
    STATSFREQ    DEV             ETAPE1                      1
    STATSFREQ    DEV             ETAPE1                      1
    Les résultats obtenus sont :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CODE_ETAPE DETAIL_ETAPE SUM(TEMPS)
    ANA
    DEV             ETAPE1                                          2
    DEV             ETAPE2
    alors qu'ils devraient etre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CODE_ETAPE DETAIL_ETAPE SUM(TEMPS)
    ANA                                                                 1.5
    DEV             ETAPE1                                          2
    DEV             ETAPE2

  6. #6
    Membre habitué
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    80
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Mayenne (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 80
    Points : 197
    Points
    197
    Par défaut
    Et avec un CASE... WHEN... ?

    Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sum(case when (a.temps is null) then 0 else a.temps end)
    "Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live." (Code for the Maintainer)
    I usually maintain my own code, so the as-if is true!

  7. #7
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut
    Bonjour Pergos

    Je ne connaissais pas cette possibilité de syntaxe, mais désolé, le résultat est le même :-(

  8. #8
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    Citation Envoyé par Pergos
    Et avec un CASE... WHEN... ?

    Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    sum(case when (a.temps is null) then 0 else a.temps end)
    a remplacer par

    C'est pas parce que ca marche que c'est bon!!
    Pensez au bouton "Résolu"
    Je ne réponds pas en privé aux questions

  9. #9
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    2ieme chose :

    essaye en supprimant la jointure "AND e.detail_etape_projet = a.detail_etape "

    il se peut que tes valeurs ne soient pas bonnes ....
    je pense que si les valeurs sont nulles il ne te fait pas la jointure, le marqueur null n'est pas présent dans l'égalité...

    essaye ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND (e.detail_etape_projet = a.detail_etape  OR ( e.detail_etape_projet IS NULL and a.detail_etape IS NULL ))
    C'est pas parce que ca marche que c'est bon!!
    Pensez au bouton "Résolu"
    Je ne réponds pas en privé aux questions

  10. #10
    Membre averti Avatar de bouvda
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    252
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Octobre 2005
    Messages : 252
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par miloux32
    a remplacer par

    Ca ne réglera pas le problème de Loko car c'est équivalent à sum(coalesce(a.temps,0)) sauf que nvl n'est pas un standard mais une fonction d'Oracle.

  11. #11
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    Citation Envoyé par bouvda
    Ca ne réglera pas le problème de Loko car c'est équivalent à sum(coalesce(a.temps,0)) sauf que nvl n'est pas un standard mais une fonction d'Oracle.
    d'ou mon second message
    C'est pas parce que ca marche que c'est bon!!
    Pensez au bouton "Résolu"
    Je ne réponds pas en privé aux questions

  12. #12
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Bonjour,
    Effectivement le problème est sur la jointure, non pas sur l'agrégat !
    Vu la syntaxe, je suppose que le SGBD est Oracle ...
    Vous pouvez faire comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT   e.code_etape,e.detail_etape, SUM(a.temps) "Temps réel" 
        FROM etapes_projets e left outer join activite a  
    		 				ON a.code_projet = e.code_projet
         					AND a.code_etape_projet = e.code_etape 
    	 					AND NVL(a.detail_etape_projet,'NOVALUE') = NVL(e.detail_etape,'NOVALUE')						
       WHERE e.code_projet = 'STATSFREQ'
    GROUP BY e.code_etape,e.detail_etape
    Je penche, donc je suis

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut
    Yes !

    Je vous confirme que les 2 solutions de Miloux32 et Crifo fonctionnent !

    Effectivement, il faudra que je prenne l'habitude de traiter différemment les valeurs nulls dans les comparaisons/jointures.

    Merci beaucoup à vous !

  14. #14
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    Citation Envoyé par Loko
    Yes !

    Je vous confirme que les 2 solutions de Miloux32 et Crifo fonctionnent !

    Effectivement, il faudra que je pense à traiter différemment les valeurs nulls dans les comparaisons/jointures.

    Merci beaucoup à vous !
    Le plus simple est de ne pas autoriser de valeur nulle dans ce cas ... mais de mettre un truc genre " ETAPE0"
    C'est pas parce que ca marche que c'est bon!!
    Pensez au bouton "Résolu"
    Je ne réponds pas en privé aux questions

  15. #15
    Membre confirmé Avatar de chrifo
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    444
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 444
    Points : 481
    Points
    481
    Par défaut
    Citation Envoyé par miloux32
    Le plus simple est de ne pas autoriser de valeur nulle dans ce cas ... mais de mettre un truc genre " ETAPE0"
    tout à fait, et cela permettrait en plus une utilisation simple des indexes (code,etape,detail)
    Je penche, donc je suis

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    344
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juillet 2004
    Messages : 344
    Points : 188
    Points
    188
    Par défaut
    Citation Envoyé par miloux32
    Le plus simple est de ne pas autoriser de valeur nulle dans ce cas ... mais de mettre un truc genre " ETAPE0"
    Oui c'est une solution mais cela complique pas mal ensuite les choses au niveau affichage/saisie par l'utilisateur :
    - afficher "vide" quand la valeur est ETAPE0
    - mettre ETAPE0 quand l'utilisateur ne saisit rien dans ce champs

    et il faut y penser à chaque fois que l'on développe une nouvelle interface.

    De plus il faut s'assurer de prendre une valeur que l'utilisateur ne tapera jamais

    C'est pourquoi je préfère avoir dès le départ des valeurs "correctes" ou "significatives".

    Merci encore.

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

Discussions similaires

  1. Problème de jointure externe
    Par calagan99 dans le forum Langage SQL
    Réponses: 5
    Dernier message: 24/04/2008, 12h12
  2. Problème avec jointure externe
    Par illight dans le forum Langage SQL
    Réponses: 1
    Dernier message: 09/04/2008, 12h23
  3. Réponses: 10
    Dernier message: 25/01/2008, 16h24
  4. Réponses: 24
    Dernier message: 24/07/2007, 17h48
  5. Problème de Jointure externe
    Par major2 dans le forum Requêtes
    Réponses: 2
    Dernier message: 11/07/2007, 17h58

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