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 29/04/2008, 10h51   #1
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
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 :
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 :
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 :
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 :
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
guitou0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 10h55   #2
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
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 :
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.
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 11h14   #3
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
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. :/
guitou0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 11h23   #4
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
En fait j'avais pas fait gaffe :

Code :
AND t2.dat <= TO_DATE ('31/03/1997', 'DD/MM/YYYY')
D
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 11h23   #5
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
En fait j'avais pas fait gaffe :

Code :
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)
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 11h57   #6
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
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. :/
guitou0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 12h03   #7
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 320
Points : 5 839
Points : 5 839
Code :
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')
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 12h17   #8
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
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.
guitou0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 12h18   #9
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 459
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 459
Points : 4 226
Points : 4 226
En fait tout simplement
Code :
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
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 13h18   #10
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
Ah oue tiens, je préfère cette syntaxe.

Merci.
guitou0 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/04/2008, 15h58   #11
Expert Confirmé Sénior
 
Avatar de mnitu
 
Homme Marius Nitu
Ingénieur développement logiciels
Inscription : octobre 2007
Messages : 3 320
Détails du profil
Informations personnelles :
Nom : Homme Marius Nitu
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 : 3 320
Points : 5 839
Points : 5 839
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.
mnitu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/04/2008, 13h35   #12
Futur Membre du Club
 
Développeur informatique
Inscription : mai 2007
Messages : 38
Détails du profil
Informations personnelles :
Âge : 32

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : mai 2007
Messages : 38
Points : 17
Points : 17
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.
guitou0 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 20h11.


 
 
 
 
Partenaires

Hébergement Web