Je cherche à faire des requêtes avec jointure similaires à la fonction
RECHERCHEV d'Excel. Les champs de mes deux tables ne sont pas liés par
des valeurs identiques, mais par plages de valeurs: L'enregistrement X
de Table1 est lié à l'enregistrement Y de Table2 pour lequel
[Table1].ChampA de X >= [Table2].BorneInf de Y et [Table1].ChampA de X
< [Table2].BorneSup de Y.
Par SQL, je m'en tire avec des requêtes du style :
SELECT ... WHERE [Table1].ChampA >= [Table2].BorneInf AND
[Table1].ChampA < [Table2].BorneSup
Le problème c'est que ces requêtes sont trop lentes à l'exécution et pas
très élégantes. D'autre part, j'aimerais me débarrasser du champ
"BorneSup", qui ne sert qu'à la requête mais n'a aucune utilité par
ailleurs (il est toujours égal au champ BorneInf de l'enregistrement
suivant).
Je précise que les intervalles entre bornes n'ont aucune régularité,
elles peuvent passer de 1 à 50, puis 32, 459, 96 etc d'un
enregistrement.à l'autre.
Y a-t-il un autre moyen, plus efficace, pour faire ce genre de requête ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Michel Walsh
Salut,
En principe, on peut essayer avec une jointure
SELECT ... FROM table1 INNER JOIN table2 ON table1.ChampA >= table2.BorneInf AND table1.ChampA < table2.BorneSup
et évidemment, on indexe les trois champs impliqués.
Pour éliminer la borne supérieure, c'est possible, mais le traitement sera probablement plus lent, car à table1.ChampA >= table2.BorneInf, il faudra ajouter une recherche sur le fait que le table2.BorneInf désiré est le MAXimum parmi tous ceux qui sont, en effet, =< table1.ChampA. Une formulation possible:
FROM table1 INNER JOIN table2 ON table1.ChampA >= table2.BorneInf WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf) FROM table2 As a WHERE a.BorneInf =< table1.ChampA)
Techniquement, un esprit éveillé peut constater qu'on peut également se contenter de faire:
FROM table1, table2 WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf) FROM table2 As a WHERE a.BorneInf =< table1.ChampA)
mais j'ai l'impression que ce serait encore plus lent, car si l'optimiseur tombe en panne, la clause WHERE sera évaluée pour un nombre encore plus grand de combinaisons d'enregistrements, dans le second cas (le WHERE étant évaluable APRÈS la jointure). La première formulation élimine, via la jointure, un grand nombre d'enregistrements, laissant moins d'enregistrements lors de l'évaluation de la clause WHERE. Évidemment, si on ne maganne pas trop la syntaxe, l'optimiseur devrait produire quelque chose de potable, même dans la seconde formulation.
Espérant être utile, Vanderghast, Access MVP
"Ribouldingue" wrote in message news:%
Bonjour !
Je cherche à faire des requêtes avec jointure similaires à la fonction RECHERCHEV d'Excel. Les champs de mes deux tables ne sont pas liés par des valeurs identiques, mais par plages de valeurs: L'enregistrement X de Table1 est lié à l'enregistrement Y de Table2 pour lequel [Table1].ChampA de X >= [Table2].BorneInf de Y et [Table1].ChampA de X < [Table2].BorneSup de Y.
Par SQL, je m'en tire avec des requêtes du style :
SELECT ... WHERE [Table1].ChampA >= [Table2].BorneInf AND [Table1].ChampA < [Table2].BorneSup
Le problème c'est que ces requêtes sont trop lentes à l'exécution et pas très élégantes. D'autre part, j'aimerais me débarrasser du champ "BorneSup", qui ne sert qu'à la requête mais n'a aucune utilité par ailleurs (il est toujours égal au champ BorneInf de l'enregistrement suivant).
Je précise que les intervalles entre bornes n'ont aucune régularité, elles peuvent passer de 1 à 50, puis 32, 459, 96 etc d'un enregistrement.à l'autre.
Y a-t-il un autre moyen, plus efficace, pour faire ce genre de requête ?
Merci !
Ribouldingue
Salut,
En principe, on peut essayer avec une jointure
SELECT ...
FROM table1 INNER JOIN table2
ON table1.ChampA >= table2.BorneInf AND table1.ChampA < table2.BorneSup
et évidemment, on indexe les trois champs impliqués.
Pour éliminer la borne supérieure, c'est possible, mais le traitement sera
probablement plus lent, car à table1.ChampA >= table2.BorneInf, il faudra
ajouter une recherche sur le fait que le table2.BorneInf désiré est le
MAXimum parmi tous ceux qui sont, en effet, =< table1.ChampA. Une
formulation possible:
FROM table1 INNER JOIN table2
ON table1.ChampA >= table2.BorneInf
WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf)
FROM table2 As a
WHERE a.BorneInf =< table1.ChampA)
Techniquement, un esprit éveillé peut constater qu'on peut également se
contenter de faire:
FROM table1, table2
WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf)
FROM table2 As a
WHERE a.BorneInf =< table1.ChampA)
mais j'ai l'impression que ce serait encore plus lent, car si l'optimiseur
tombe en panne, la clause WHERE sera évaluée pour un nombre encore plus
grand de combinaisons d'enregistrements, dans le second cas (le WHERE étant
évaluable APRÈS la jointure). La première formulation élimine, via la
jointure, un grand nombre d'enregistrements, laissant moins
d'enregistrements lors de l'évaluation de la clause WHERE. Évidemment, si on
ne maganne pas trop la syntaxe, l'optimiseur devrait produire quelque chose
de potable, même dans la seconde formulation.
Espérant être utile,
Vanderghast, Access MVP
"Ribouldingue" <nospam@free.fr> wrote in message
news:%23zpDD7jjDHA.2488@TK2MSFTNGP12.phx.gbl...
Bonjour !
Je cherche à faire des requêtes avec jointure similaires à la fonction
RECHERCHEV d'Excel. Les champs de mes deux tables ne sont pas liés par
des valeurs identiques, mais par plages de valeurs: L'enregistrement X
de Table1 est lié à l'enregistrement Y de Table2 pour lequel
[Table1].ChampA de X >= [Table2].BorneInf de Y et [Table1].ChampA de X
< [Table2].BorneSup de Y.
Par SQL, je m'en tire avec des requêtes du style :
SELECT ... WHERE [Table1].ChampA >= [Table2].BorneInf AND
[Table1].ChampA < [Table2].BorneSup
Le problème c'est que ces requêtes sont trop lentes à l'exécution et pas
très élégantes. D'autre part, j'aimerais me débarrasser du champ
"BorneSup", qui ne sert qu'à la requête mais n'a aucune utilité par
ailleurs (il est toujours égal au champ BorneInf de l'enregistrement
suivant).
Je précise que les intervalles entre bornes n'ont aucune régularité,
elles peuvent passer de 1 à 50, puis 32, 459, 96 etc d'un
enregistrement.à l'autre.
Y a-t-il un autre moyen, plus efficace, pour faire ce genre de requête ?
SELECT ... FROM table1 INNER JOIN table2 ON table1.ChampA >= table2.BorneInf AND table1.ChampA < table2.BorneSup
et évidemment, on indexe les trois champs impliqués.
Pour éliminer la borne supérieure, c'est possible, mais le traitement sera probablement plus lent, car à table1.ChampA >= table2.BorneInf, il faudra ajouter une recherche sur le fait que le table2.BorneInf désiré est le MAXimum parmi tous ceux qui sont, en effet, =< table1.ChampA. Une formulation possible:
FROM table1 INNER JOIN table2 ON table1.ChampA >= table2.BorneInf WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf) FROM table2 As a WHERE a.BorneInf =< table1.ChampA)
Techniquement, un esprit éveillé peut constater qu'on peut également se contenter de faire:
FROM table1, table2 WHERE table2.BorneInf = ( SELECT MAX( a.BorneInf) FROM table2 As a WHERE a.BorneInf =< table1.ChampA)
mais j'ai l'impression que ce serait encore plus lent, car si l'optimiseur tombe en panne, la clause WHERE sera évaluée pour un nombre encore plus grand de combinaisons d'enregistrements, dans le second cas (le WHERE étant évaluable APRÈS la jointure). La première formulation élimine, via la jointure, un grand nombre d'enregistrements, laissant moins d'enregistrements lors de l'évaluation de la clause WHERE. Évidemment, si on ne maganne pas trop la syntaxe, l'optimiseur devrait produire quelque chose de potable, même dans la seconde formulation.
Espérant être utile, Vanderghast, Access MVP
"Ribouldingue" wrote in message news:%
Bonjour !
Je cherche à faire des requêtes avec jointure similaires à la fonction RECHERCHEV d'Excel. Les champs de mes deux tables ne sont pas liés par des valeurs identiques, mais par plages de valeurs: L'enregistrement X de Table1 est lié à l'enregistrement Y de Table2 pour lequel [Table1].ChampA de X >= [Table2].BorneInf de Y et [Table1].ChampA de X < [Table2].BorneSup de Y.
Par SQL, je m'en tire avec des requêtes du style :
SELECT ... WHERE [Table1].ChampA >= [Table2].BorneInf AND [Table1].ChampA < [Table2].BorneSup
Le problème c'est que ces requêtes sont trop lentes à l'exécution et pas très élégantes. D'autre part, j'aimerais me débarrasser du champ "BorneSup", qui ne sert qu'à la requête mais n'a aucune utilité par ailleurs (il est toujours égal au champ BorneInf de l'enregistrement suivant).
Je précise que les intervalles entre bornes n'ont aucune régularité, elles peuvent passer de 1 à 50, puis 32, 459, 96 etc d'un enregistrement.à l'autre.
Y a-t-il un autre moyen, plus efficace, pour faire ce genre de requête ?