Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 25/08/2011, 17h31   #1
Candidat au titre de Membre du Club
 
Homme Frédéric
Administrateur de base de données
Inscription : avril 2011
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 27
Localisation : France, Cher (Centre)

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Service public

Informations forums :
Inscription : avril 2011
Messages : 9
Points : 12
Points : 12
Par défaut Jointure externe avec conditions supplémentaires

Bonjour,

J'ai tenté de chercher sur le forum mais pas évident quand on ne sait pas soit même comment définir le problème :s

Je souhaiterais faire une jointure externe entre deux tables dont voici les structures imposées :

- individu (no_individu)
- telephone (id,no_individu,no_telephone,type,statut)

Dans la table téléphone il n'y a d'enregistrements que si l'individu n'a effectivement un téléphone. D'où mon commencement de piste vers une jointure externe.

De plus un même individu peut avoir plusieurs téléphones de type différent.
Par exemple, on aura :
individu n°4 avec un téléphone fixe 02xxxxxxxx.
individu n°4 avec un téléphone mobile 02xxxxxxxx
individu n°5 aucune téléphone

Du coup dans ma requête ressemble à ça :

Code :
1
2
3
SELECT *
FROM individu,telephone
WHERE individu.no_individu=telephone.no_individu(+)
Jusque là ca marche, j'ai bien tout le monde avec ou sans numéro de téléphone
Mais quand je rajoute une condition supplémentaire, par exemple je ne veux que les téléphone fixes :

Code :
1
2
3
4
SELECT *
FROM individu,telephone
WHERE individu.no_individu=telephone.no_individu(+)
AND type='fixe'
Ca m'exclut tout ceux qui n'ont pas de téléphone.
J'ai essayé avec :
Code :
AND (type='fixe' OR type IS NULL)
Mais que nenni !

Pour info, je travaille sur Oracle 10g R2.

Merci d'avance si vous avez des pistes d'investigation.

Frédéric.
fbms18 est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 25/08/2011, 18h00   #2
Rédacteur
 
Inscription : décembre 2002
Messages : 2 387
Détails du profil
Informations personnelles :
Localisation : France, Var (Provence Alpes Côte d'Azur)

Informations forums :
Inscription : décembre 2002
Messages : 2 387
Points : 3 272
Points : 3 272
En bref, dans les jointures externes à la mode Oracle, il faut, dans le WHERE, rajouter le (+) sur chaque colonne appartenant à la table externe.

Code :
1
2
3
4
SELECT *
FROM individu,telephone
WHERE individu.no_individu=telephone.no_individu(+)
AND type(+)='fixe'
Le mieux serait quand même d'adopter la syntaxe normalisée à base de LEFT OUTER JOIN, qui est disponible depuis Oracle 9i.
__________________
Consultant / formateur Oracle indépendant
Certifié OCP 10g et 11g, sécurité 11g
Pomalaix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/08/2011, 08h58   #3
Candidat au titre de Membre du Club
 
Homme Frédéric
Administrateur de base de données
Inscription : avril 2011
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 27
Localisation : France, Cher (Centre)

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Service public

Informations forums :
Inscription : avril 2011
Messages : 9
Points : 12
Points : 12
Quelle patate ! Je mettais le (+) au mauvais endroit

Merci beaucoup pour la réponse.
Ca ressemble donc à ça si jamais il y a une autre personne qui passe par là pour la même question :
Code :
1
2
3
4
SELECT * 
FROM individu,telephone 
LEFT OUTER JOIN ON (individu.no_individu=telephone.no_individu 
AND type='fixe')
Bonne journée et encore merci.

Frédéric.
fbms18 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/08/2011, 09h32   #4
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
Bonjour,
Code :
1
2
3
4
5
 
SELECT *
FROM individu,telephone
WHERE individu.no_individu=telephone.no_individu(+)
AND type='fixe'
C'est tout à fait logique que la requête ci-dessus ne fonctionne pas correctement. En effet, par la clause suivante:

Code :
1
2
 
WHERE individu.no_individu=telephone.no_individu(+)
nous voulons qu'Oracle nous renvoi tous les enregistrements de la table individu qui possèdent un correspondant dans la table telephone. De plus,
nous demandons à Oracle que, lorsque cette correspondance n'existe pas à cause de la table telephone, d’être gentil quand même en nous affichant les enregistrements de la table individu et en remplaçant les enregistrements manquants de la table telephone par des NULLs.

Donc, suivez bien, que dans le cas d'absence de correspondance entre les deux tables, les informations provenant de la table téléphone sont NULLs

Alors comment voudriez-vous dans ce cas que la clause suivante fonctionne correctement

Code :
1
2
 
AND telephone.type ='fixe'
NULL ne peut pas être égale à fixe.

D'où la proposition de pomalaix

Code :
1
2
 
AND type(+)='fixe'

Conclusion
A chaque fois que vous avez une jointure entre deux tables qui ressemble à ceci

Code :
1
2
3
 
WHERE t1.id = t2.id(+)
AND   t2.colx = valx
alors le (+) est inutile et peut être supprimé.
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/08/2011, 09h43   #5
Candidat au titre de Membre du Club
 
Homme Frédéric
Administrateur de base de données
Inscription : avril 2011
Messages : 9
Détails du profil
Informations personnelles :
Nom : Homme Frédéric
Âge : 27
Localisation : France, Cher (Centre)

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Service public

Informations forums :
Inscription : avril 2011
Messages : 9
Points : 12
Points : 12
Citation:
Envoyé par Mohamed.Houri Voir le message
Bonjour,
Alors comment voudriez-vous dans ce cas que la clause suivante fonctionne correctement
C'est bien la raison pour laquelle je suis venu poser la question ici, je savais bien que ca ne fonctionnait pas

Citation:
Envoyé par Mohamed.Houri Voir le message
Conclusion
A chaque fois que vous avez une jointure entre deux tables qui ressemble à ceci

Code :
1
2
3
 
WHERE t1.id = t2.id(+)
AND   t2.colx = valx
alors le (+) est inutile et peut être supprimé.
Je ne suis pas d'accord. Le but est pour moi de récupérer les enregistrements des deux tables même s'il n'y a de correspondance. Si je supprime les (+) je perds ces enregistrements qui me sont précieux. Pour exemple, ce n'est pas parce qu'un individu n'a pas téléphone dans mon exemple qu'il doit être exclu des listings de paye ^^ Je vous laisse transmettre cette info à mes collègues qui se feront une joie de vous accueillir ^^

En tout cas, j'ai bien réussi à faire ce que je voulais, merci Pomalaix.
fbms18 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/08/2011, 10h05   #6
Membre expérimenté
 
Homme Mohamed Houri
Inscription : mars 2010
Messages : 286
Détails du profil
Informations personnelles :
Nom : Homme Mohamed Houri
Localisation : France

Informations forums :
Inscription : mars 2010
Messages : 286
Points : 563
Points : 563
La conclusion ne concernait pas votre cas bien précis. Elle s'adresse en général à ceux qui veulent comprendre pourquoi à l'origine vous n'aviez pas le résultat adéquat.
__________________
Bien Cordialement
www.hourim.wordpress.com
Mohamed.Houri est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 02h56.


 
 
 
 
Partenaires

Hébergement Web