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 :

LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)


Sujet :

Langage SQL

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Points : 6
    Points
    6
    Par défaut LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)
    Salut,
    Oracle 8 (ou 7 ?) ne comprend les requêtes SQL "... LEFT JOIN ....". Il faut utiliser les (+).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT t_tournee.description, t_lieu.cle 
    FROM t_tournee, t_passage, t_lieu 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu=t_lieu.cle 
    AND t_lieu.cle=19
    Cette requête serait sensée renvoyer les descriptions de TOUTES les tournées. Si celles-ci ne contient pas les lieu 19 alors, t_passage.cle=null, si la tournée le contient t_lieu.cle=19.
    C'est-ce que j'aimerais bien que ça produise mais en réalité ça agit comme une jointure normale (interne) car le résultat ne comprend pas les tournées qui ne contienent pas le lieu 19
    C'est traumatisant!

    --
    LoÏK

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 102
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 102
    Points : 28 392
    Points
    28 392
    Par défaut Re: LEFT JOIN avec Oracle 8i ne va pas... doit utiliser (+)
    Et en faisant tout bêtement ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu=19

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Ma requête en réalité est + complexe, mais oui c'est pareil... il en manque toujours avec celle-là aussi.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT t_tournee.description, t_passage.ref_lieu
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu=19;
    ...
    7 ligne(s) sélectionnée(s).
    et...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select * from t_tournee;
    ...
    8 ligne(s) sélectionnée(s).

  4. #4
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    mais en réalité ça agit comme une jointure normale (interne) car le résultat ne comprend pas les tournées qui ne contienent pas le lieu 19
    Normal puisque tu demandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu=19
    La jointure externe ajoute bien les lignes que tu veux et ton where les élimine.
    Il faut sans doute ajouter quelque chose pour accepter les lignes ajoutées (genre : OR t_passage.ref_lieu IS NULL)

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    J'ai trouvé la solution.
    Merci à tous!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu(+)=19
    C'est vrai que la clause passage_ref_lieu limitait les tuples simplement à ceux qui avaient ref_lieu=19. C'était évident, mais trop simple...
    En faisant un OR ... ça ne pouvait pas marcher non plus...
    Il fallait faire une seconde jointure externe!

  6. #6
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Essaye voir si la requête suivante est plus performante et fonctionne bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND NVL(t_passage.ref_lieu,19)=19

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Ca marche aussi bien c'est vrai !!! Sans jointure externe! :o
    Pourquoi?
    J'ai été jeter un oeil dans la doc ? et ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    NVL (exp1, exp2) : retourne exp2 si exp1 est NULL, exp1 sinon.
     
     
    Par exemple, on peut s'en servir pour remplacer NULL par des étoiles à l'affichage 
       SELECT NVL (nom_col,'*****') ... 
    ou pour éliminer les occurrences ayant 0 et garder celles qui ont NULL dans une colonne de type numérique en utilisant la condition : 
       WHERE NVL (nom_col,1) <> 0
    Voilà qui éclaire...
    Si ef_lieu est = à 19, la condition est vérifiée.
    Si ref_lieu est NULL, il le remplace par 19 et la condition est vérifiée.
    Si ref_lieu est <> de 19, la condition n'est pas vérifiée.

    voilà exactement ce que je cherchais!

    Mais, au niveau des performances, n'est-ce pas équivalent?
    Est-ce que quand on fait une jointure externe, ce n'est pas la même opération au fond?
    Comment on peut faire pour voir le temps de transaction dans Oracle?
    Que de questions existentielles!

  8. #8
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Alors pour les performances j'en sais rien c'est pourquoi je voulais que tu testes

    M'est avis qu'il vaut mieux 1 jointure externe que 2

    Comment ça marche : c'est simple avec une jointure externe si la ligne n'est pas trouvé dans la table jointurée les colonnes sont considérées NULL, voila comment on peut utiliser le NVL

    Pour les perfs essayent la requête en faisant ceci avant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    set timing on
    set autotrace on

  9. #9
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    En faisant un OR ... ça ne pouvait pas marcher non plus
    Il me semble que le nvl qui marche fait exactement ce qu'aurait fait un OR (fonctionnellement en tout cas) donc tant qu'à faire des tests, cela serait intéressant d'avoir les 3 méthodes.
    En remplaçant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NVL(t_passage.ref_lieu,19)=19
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (t_passage.ref_lieu = 19 OR t_passage.ref_lieu is null)

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2004
    Messages : 8
    Points : 6
    Points
    6
    Par défaut
    Voilà le grand résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND NVL(t_passage.ref_lieu,19)=19;
    ...
    8 ligne(s) sélectionnée(s).
    Ecoulé : 00 :00 :00.03
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND (t_passage.ref_lieu = 19 OR t_passage.ref_lieu is null);
    ...
    8 ligne(s) sélectionnée(s).
    Ecoulé : 00 :00 :00.03
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT t_tournee.description, t_passage.ref_lieu 
    FROM t_tournee, t_passage 
    WHERE t_tournee.cle=t_passage.ref_tournee (+) 
    AND t_passage.ref_lieu(+)=19 
    ;
    ...
    9 ligne(s) sélectionnée(s).
    Ecoulé : 00 :00 :00.03
    Alors, il ya d'abord une remarque à faire, c'est que le temps écoulé n'est pas significatif. Il n'y a pas assez d'enregistrements. Peut-être que dans 10 ans il y en aura assez...

    C'est vrai que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    NVL(t_passage.ref_lieu,19)=19
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     (t_passage.ref_lieu = 19 OR t_passage.ref_lieu is null)
    sont strictement équivalents. Ce qui est logique d'ailleurs...

    Mais il y a plus grave!!! :o C'est que le nombre de résultats n'est pas équivalent. 8 pour les requêtes avec la condition et 9 pour celui avec jointure externe.
    Quel est donc ce 9ème enregistrement?
    C'est tout simplement une tournée qui ne possède aucun passage associé.
    Je crois donc qu'il est impossible de se passer de la deuxième jointure externe. Enfait la condition d'inclusion dans l'ensemble résultat ne se réduit pas simplement à ce que le lieu de passage soit le 19ème ou pas mais aussi à ce qu'il y ait aucun passage associé. Enfin, je crois...
    C'est chouette le SQL!

  11. #11
    Expert éminent sénior
    Avatar de orafrance
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    15 967
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 15 967
    Points : 19 075
    Points
    19 075
    Par défaut
    Effectivement... Oracle c'est magique 8)

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

Discussions similaires

  1. [MySQL-5.5] LEFT JOIN avec MAX qui ne me retourne pas les bonnes données
    Par Gloup dans le forum Requêtes
    Réponses: 4
    Dernier message: 05/05/2014, 17h26
  2. left join avec max(date)
    Par supernicoco dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/10/2008, 08h53
  3. 2 SUM 2 LEFT JOIN 3 tables et ça marche pas.
    Par thanaos dans le forum Requêtes
    Réponses: 2
    Dernier message: 29/05/2007, 09h27
  4. Left join avec 3 tables
    Par MathiasMathias dans le forum Langage SQL
    Réponses: 1
    Dernier message: 10/04/2007, 00h45
  5. LEFT JOIN sous Oracle 8i
    Par alexadvance dans le forum Oracle
    Réponses: 11
    Dernier message: 02/11/2005, 11h21

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