Bonjour,

J'ai une requête où j'ai des jointures "conditionnelles", je m'explique :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
  Table A   |    Table B     |    Table C
---------------------------------------
Propriete1  |   Propriete2   |  Propriete3
Propriete4  |   Propriete5   |  Propriete6
J'ai une jointure sur les tables A et B, entre Propriete1 et Propriete2.
Selon la valeur Propriete4 de mon "enregistrement", je fais une jointure sur les tables B et C entre les Propriete2 et Propriete3, ou je fais une jointure sur les tables B et C entre les Propriete5 et Propriete6.

C'est peut-être pas trés clair, voici le bout de sql correspondant :
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
SELECT    *
FROM      A,
          B,
          C
WHERE     A.Propriete1 = B.Propriete2
AND       B.Propriete2 = CASE
                              WHEN A.Propriete4 = 1
                                  THEN C.Propriete3
                              ELSE B.Propriete2 -- condition non-respectée, du coup pour ne pas faire de jointure, je fais une auto-jointure...
                         END
AND       B.Propriete5 = CASE
                              WHEN A.Propriete4 = 1
                                  THEN B.Propriete5
                              ELSE C.Propriete6 -- auto-jointure...
                         END
Bon, c'est un peu de la bidouille avec du code SQL pas beau du tout... le coup de l'auto-jointure, j'imagine que c'est pas top du tout...

Mais, ce n'est pas tout, car cette "auto-jointure" ne fonctionne pas avec les valeurs NULL... du coup, j'ai du rajouter des ISNULL devant chaque propriete pour que la jointure "fonctionne"...

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
SELECT    *
FROM      A,
          B,
          C
WHERE     A.Propriete1 = B.Propriete2
AND       ISNULL(B.Propriete2,-1) = CASE
                                        WHEN A.Propriete4 = 1
                                            THEN C.Propriete3
                                        ELSE ISNULL(B.Propriete2,-1) -- auto-jointure...
                                    END
AND       ISNULL(B.Propriete5,-1) = CASE
                                        WHEN A.Propriete4 = 1
                                            THEN  ISNULL(B.Propriete5,-1)
                                        ELSE C.Propriete6 -- auto-jointure...
                                    END
Donc, déjà, même si je me doute de la réponse, est-ce que c'est "propre" de faire tout ça ?

Et, les performances ne sont pas trop au rendez-vous, est-ce les multiples CASE et ISNULL qui dégradent les performances ? ou le fait d'utiliser des fonctions sur les jointures (j'ai lu que les index n'étaient pas utilisé lorsque des fonctions sont utilisées sur les "clés de jointures")

Si qq'un a une idée pour avoir du SQL plus propre ?

Merci d'avance,

A+