Problème de jointure externe avec les notations ANSI et Oracle
Bonjour,
J'ai actuellement un problème "relativement" gênant avec une requete au sein de laquelle je devrais utiliser une jointure externe.
Ca ne marche simplement pas en notation ANSI (avec "RIGHT/LEFT OUTER JOIN")... Et ca ne marche que partiellement en notation oracle (avec "(+)"). Je m'explique, en utilisant la notation ANSI, le résultat est semblable à si j'utilisais une jointure interne (càd que le "résultat nul" ne s'affiche pas), alors qu'en utilisant la notation Oracle, j'ai bel et bien le résultat escompté.
Mais malheureusement, de par ses limitations (impossibilité d'utiliser les IN ou les OR sur les colonnes de la table ou encore des > et < sur les colonnes de la jointure), la notation Oracle ne me convient pas non plus, car du coup, les conditions sont bien trop restrictives.
Dans les requetes suivants, j'ai échangé les tables originelles par des "FROM dual" pour rendre l'exemple portable et non lié a des données qui bougent. Mes ensemble de données sont comme suit :
###############
# _______d_______ #
###############
# 2004 # 2 # 70'000 #
# 2004 # 9 # 62'000 #
# 2005 # 0 # 32'268 #
# 2005 # 2 # 66'600 #
# 2005 # 9 # 12'134 #
###############
####
# t #
####
# 0 #
# 2 #
# 9 #
####
Et en faisant une jointure externe entre t et d, j'aimerais obtenir ceci :
###############
# ____resultat_____ #
###############
# ____ # 0 # _____ #
# 2004 # 2 # 70'000 #
# 2004 # 9 # 62'000 #
###############
Voici donc comment j'ai écrit ma requete en format ANSI :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| SELECT d.dra_adec, dra_tcom, dra_avss
FROM (SELECT '2004' AS dra_adec, '2' AS dra_tcom, 3000 AS dra_avss FROM dual UNION
SELECT '2004' AS dra_adec, '9' AS dra_tcom, 458.5 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '0' AS dra_tcom, 978.25 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '2' AS dra_tcom, 12541.1 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '9' AS dra_tcom, 40.5 AS dra_avss FROM dual) d
RIGHT OUTER JOIN
(SELECT '0' AS dra_tcom FROM dual UNION
SELECT '2' AS dra_tcom FROM dual UNION
SELECT '9' AS dra_tcom FROM dual) t USING (dra_tcom)
WHERE d.dra_adec = 2004
ORDER BY d.dra_adec, dra_tcom; |
Mon résultat est malheureusement le suivant :
###############
# ____resultat_____ #
###############
# 2004 # 2 # 70'000 #
# 2004 # 9 # 62'000 #
###############
L'enregistrement avec la clé à 0 et le reste à NULL n'est donc pas présent. J'ai donc reformaté la requete pour utiliser la notation Oracle :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| SELECT d.dra_adec, t.dra_tcom, dra_avss
FROM (SELECT '2004' AS dra_adec, '2' AS dra_tcom, 3000 AS dra_avss FROM dual UNION
SELECT '2004' AS dra_adec, '9' AS dra_tcom, 458.5 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '0' AS dra_tcom, 978.25 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '2' AS dra_tcom, 12541.1 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '9' AS dra_tcom, 40.5 AS dra_avss FROM dual) d,
(SELECT '0' AS dra_tcom FROM dual UNION
SELECT '2' AS dra_tcom FROM dual UNION
SELECT '9' AS dra_tcom FROM dual) t
WHERE d.dra_adec(+) = 2004
AND d.dra_tcom(+) = t.dra_tcom
ORDER BY d.dra_adec, t.dra_tcom; |
Le résultat est cette fois ci conforme à ce que j'attendais :
###############
# ____resultat_____ #
###############
# ____ # 0 # _____ #
# 2004 # 2 # 70'000 #
# 2004 # 9 # 62'000 #
###############
Mais maintenant, j'aimerais completer un peu la requete afin que plutot que de rechercher les données de l'année 2004, je recherche les données à partir de 2004. Je remplace donc le "=" par ">=" :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| SELECT d.dra_adec, t.dra_tcom, dra_avss
FROM (SELECT '2004' AS dra_adec, '2' AS dra_tcom, 3000 AS dra_avss FROM dual UNION
SELECT '2004' AS dra_adec, '9' AS dra_tcom, 458.5 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '0' AS dra_tcom, 978.25 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '2' AS dra_tcom, 12541.1 AS dra_avss FROM dual UNION
SELECT '2005' AS dra_adec, '9' AS dra_tcom, 40.5 AS dra_avss FROM dual) d,
(SELECT '0' AS dra_tcom FROM dual UNION
SELECT '2' AS dra_tcom FROM dual UNION
SELECT '9' AS dra_tcom FROM dual) t
WHERE d.dra_adec(+) >= 2004
AND d.dra_tcom(+) = t.dra_tcom
ORDER BY d.dra_adec, t.dra_tcom; |
Mais la de nouveau, je n'obtiens pas ce que je veux, mais simplement :
###############
# _______d_______ #
###############
# 2004 # 2 # 70'000 #
# 2004 # 9 # 62'000 #
# 2005 # 0 # 32'268 #
# 2005 # 2 # 66'600 #
# 2005 # 9 # 12'134 #
###############
Il manque donc l'enregistrement
# ____ # 0 # _____ #
Je suis un peu perdu du coup, avec la notation Oracle je n'arrive pas à faire tout ce que je veux et avec la notation ANSI je n'obtiens pas les bons résultats. Ou est-ce que je me suis trompé?
Merci pour la lecture de ce pavé ;)
Lucas