par
Hubert Roksor » 05 mars 2006, 09:57
Avant toute chose, puisque ta table semble pouvoir avoir des ex-æquo il te faut définir un ordre unique. Pour l'exemple, on prendra "lettre, id". Je te conseille de définir l'ordre du champs de départage (le second champs pour trier les ex-æquo) identique au classement premier. En d'autres termes: tu devais utiliser "lettre ASC, id ASC" ou "lettre DESC, id DESC". Cela aura pour effet d'inverser la position des deux "b" de ton exemple, mais permettra à MySQL de faire un excellent usage de l'index que tu crééras sur "lettre, id".
Le classement intégral correspondant à ton exemple (mis à part le nouveau départage des deux "b") serait donc:
Il n'y a pas de solution magique, le plus simple pour toi sera de récupérer l'enregistrement (id=3), puis le précédent, puis le suivant. Par exemple:
Code : Tout sélectionner
SELECT *
FROM table /* précédent */
WHERE lettre < 'm' /* évidemment, le 'm' provient de la requête précédente */
OR (lettre = 'm' AND id < 3)
ORDER BY lettre DESC, id DESC /* ordre inverse du classement intégral */
LIMIT 1
Code : Tout sélectionner
SELECT *
FROM table /* suivant */
WHERE lettre > 'm'
OR (lettre = 'm' AND id > 3)
ORDER BY lettre ASC, id ASC
LIMIT 1
D'autres solutions existent, mais elles seront généralement moins performantes. On pourrait obtenir la même chose en une seul requête, mais ça prendrait deux fois plus de temps que ces 3 requêtes.
Au fait, au cas où tu ne le saurais pas, ce qui se trouve entre /* et */ est ignoré par MySQL, ce sont des commentaires.
Avant toute chose, puisque ta table semble pouvoir avoir des ex-æquo il te faut définir un ordre unique. Pour l'exemple, on prendra "lettre, id". Je te conseille de définir l'ordre du champs de départage (le second champs pour trier les ex-æquo) identique au classement premier. En d'autres termes: tu devais utiliser "lettre ASC, id ASC" ou "lettre DESC, id DESC". Cela aura pour effet d'inverser la position des deux "b" de ton exemple, mais permettra à MySQL de faire un excellent usage de l'index que tu crééras sur "lettre, id".
Le classement intégral correspondant à ton exemple (mis à part le nouveau départage des deux "b") serait donc:
[code]SELECT *
FROM table
ORDER BY lettre ASC, id ASC[/code]
Il n'y a pas de solution magique, le plus simple pour toi sera de récupérer l'enregistrement (id=3), puis le précédent, puis le suivant. Par exemple:
[code]SELECT *
FROM table
WHERE id = 3[/code]
[code]SELECT *
FROM table /* précédent */
WHERE lettre < 'm' /* évidemment, le 'm' provient de la requête précédente */
OR (lettre = 'm' AND id < 3)
ORDER BY lettre DESC, id DESC /* ordre inverse du classement intégral */
LIMIT 1[/code]
[code]SELECT *
FROM table /* suivant */
WHERE lettre > 'm'
OR (lettre = 'm' AND id > 3)
ORDER BY lettre ASC, id ASC
LIMIT 1[/code]
D'autres solutions existent, mais elles seront généralement moins performantes. On pourrait obtenir la même chose en une seul requête, mais ça prendrait deux fois plus de temps que ces 3 requêtes.
Au fait, au cas où tu ne le saurais pas, ce qui se trouve entre /* et */ est ignoré par MySQL, ce sont des commentaires.