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

SQL Oracle Discussion :

Jointure externe, qui ne retourne rien.


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut Jointure externe, qui ne retourne rien.
    Salut tout le monde.

    Oui un post de plus sur les jointures mais là je sèche et mes recherches n'apportent rien.

    J'essaie de faire une requête sur une table avec une jointure sur elle même, mais avec une jointure à gauche ça ne me retourne rien.

    D'abord la table avec ses données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    create table TEST
    (NUM VARCHAR2(4 BYTE),
    MOIS NUMBER(2),
    DAT DATE)
     
    insert into test values('9999', 1, TO_DATE ('31/01/1998', 'DD/MM/YYYY'))
    insert into test values('9999', 2, TO_DATE ('28/02/1998', 'DD/MM/YYYY'))
    insert into test values('9999', 3, TO_DATE ('31/03/1998', 'DD/MM/YYYY'))insert into test values('9999', 4, TO_DATE ('30/04/1998', 'DD/MM/YYYY'))
    Et ensuite mes requête avec les résultats :
    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
    SELECT *
      FROM TEST t1
     WHERE t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
    --Row#	NUM	MOIS	DAT
    --1	9999	1	31/01/1998
    --2	9999	2	28/02/1998
    --3	9999	3	31/03/1998
     
    SELECT *
      FROM TEST t1 LEFT OUTER JOIN TEST t2 ON t1.mois = t2.mois
                                              AND t1.num = t2.num
     WHERE t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
       AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')
    --Row#	NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    --1	NULL	NULL	NULL	NULL	NULL	NULL
     
    SELECT *
      FROM TEST t1, TEST t2
     WHERE t1.mois(+) = t2.mois
       AND t1.num(+) = t2.num
       AND t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
       AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')
    --Row#	NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    --1	NULL	NULL	NULL	NULL	NULL	NULL
    Pourtant les jointures fonctionnent correctement sans les conditions :
    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
    SELECT *
      FROM TEST t1 LEFT OUTER JOIN TEST t2 ON t1.mois = t2.mois
                                              AND t1.num = t2.num
     WHERE t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
    --Row#	NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    --1	9999	1	31/01/1998	9999	1	31/01/1998
    --2	9999	2	28/02/1998	9999	2	28/02/1998
    --3	9999	3	31/03/1998	9999	3	31/03/1998
     
    SELECT *
      FROM TEST t1, TEST t2
     WHERE t1.mois(+) = t2.mois
       AND t1.num(+) = t2.num
       AND t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
    --Row#	NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    --1	9999	1	31/01/1998	9999	1	31/01/1998
    --2	9999	2	28/02/1998	9999	2	28/02/1998
    --3	9999	3	31/03/1998	9999	3	31/03/1998
    J'espérais avoir comme résultat avec la jointure à gauche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    --Row#	NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    --1	9999	1	31/01/1998	NULL	NULL	NULL	
    --2	9999	2	28/02/1998	NULL	NULL	NULL	
    --3	9999	3	31/03/1998	NULL	NULL	NULL
    Je me trompe quelque part dans mes requêtes ou alors il y a quelque chose que j'ignore ?

    Note : Oracle 9i

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Je pense que tu inverses les jointures externes.

    Le (+) est du côté de la table qui peut avoir aucune donnée (et donc renvoyer NULL), donc ce serait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHERE t1.mois = t2.mois (+)
       AND t1.num = t2.num (+)
    Pour le left outer join - que je ne maitrise pas - ça doit être pareil, remplace le par right outer join.

  3. #3
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut
    Effectivement je me suis trompé dans ma requête avec la syntaxe (+). Le (+) doit se trouver du coté opposé à celui où l'on ne veut pas de réponses NULL.

    Par contre pour la syntaxe avec le left c'est bon, le left indique le coté sur lequel se base la requête (et donc celui où il n'y aura pas de null) dans la condition qui suit.
    Avec "LEFT OUTER JOIN TEST t2 ON t1.mois = t2.mois" le t1.mois est à gauche dans la condition.

    Dans le doute j'ai changé pour un right (et remit les (+) à la bonne place), mais toujours aucun résultat. :/

  4. #4
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    En fait j'avais pas fait gaffe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')
    D

  5. #5
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    En fait j'avais pas fait gaffe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')
    t2.dat est NULL dans ton cas !

    Rajoute juste un NVL ou un (OR IS NULL)

  6. #6
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut
    C'est pourtant le principe d'une jointure externe d'avoir un résultat même si les conditions de la requête font qu'il soit null.

    Enfin j'ai quand même testé ta solution mais non toujours aucun résultat.

    Je teste les même requête sous sql-server et pareil, je comprends pas. :/

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT *
      FROM TEST t1 LEFT OUTER JOIN (Select * from test
                                    WHERE dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')) t2
                                     ON t1.mois = t2.mois
                                    AND t1.num = t2.num
    Where t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')

  8. #8
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut
    Bon ben mnitu a fait le minimum syndicale pour sa réponse mais faut reconnaître que ça marche.
    Je pense que je comprend un peu mieux du coup, avec ma requête la condition sur le t2.dat s'appliquait sur un premier résultat et donc rien n'était retourné.

    Bref, merci McM pour ton temps et mnitu pour la solution.

  9. #9
    McM
    McM est déconnecté
    Expert éminent

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    En fait tout simplement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT *
      FROM MCTEST t1 
    LEFT OUTER JOIN MCTEST t2 ON t1.mois = t2.mois  AND t1.num = t2.num AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY') 
     WHERE t1.dat <= TO_DATE ('31/03/1998', 'DD/MM/YYYY')
     
    NUM	MOIS	DAT	NUM_1	MOIS_1	DAT_1
    9999	3	31/03/1998			
    9999	2	28/02/1998			
    9999	1	31/01/1998

  10. #10
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut
    Ah oue tiens, je préfère cette syntaxe.

    Merci.

  11. #11
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

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

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par guitou0 Voir le message
    Ah oue tiens, je préfère cette syntaxe.

    Merci.
    Je remarque que ma syntaxe t'a permis de comprendre, n'est pas vrai ?
    Désolé, pour être laconique parfois mais je n'ai pas toujours le temps pendant la journée.

  12. #12
    Nouveau membre du Club
    Développeur informatique
    Inscrit en
    Mai 2007
    Messages
    38
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2007
    Messages : 38
    Points : 37
    Points
    37
    Par défaut
    Oui j'ai compris des trucs avec ta syntaxe, merci.

    Et au final c'est elle que j'ai retenue, puisqu'en fait sur l'exemple que j'ai donné la tienne et celle de McM donne le même résultat, mais sur ma base avec des conditions supplémentaires ça n'est plus le cas.

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

Discussions similaires

  1. [MySQL] Requête qui ne retourne rien
    Par baleiney dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 28/06/2006, 18h29
  2. jointure externe qui retourne 1 ligne par enregistrement
    Par goony dans le forum Langage SQL
    Réponses: 5
    Dernier message: 11/05/2006, 17h51
  3. SELECT qui ne retourne rien à cause d'anti-slash
    Par mikyfpc dans le forum Outils
    Réponses: 8
    Dernier message: 07/08/2005, 23h04
  4. Jointure externe qui ne fonctionne pas
    Par Guizz dans le forum Langage SQL
    Réponses: 3
    Dernier message: 05/02/2004, 12h26
  5. [ jointure externe ] j'y pompe rien
    Par jaimepasteevy dans le forum Langage SQL
    Réponses: 3
    Dernier message: 16/12/2003, 17h57

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