Une option serait quelque chose comme :
select the_value,
abs(the_value - 14) as distance_from_test
from the_table
order by distance_from_test
limit 1
Pour sélectionner un enregistrement aléatoire, vous pouvez ajouter , rand()
au order by
clause. L'inconvénient de cette méthode est que vous ne tirez aucun avantage des indices car vous devez trier sur la valeur dérivée distance_from_test
.
Si vous avez un index sur the_value
et vous relâchez votre exigence pour que le résultat soit aléatoire en cas d'égalité, vous pouvez effectuer une paire de requêtes à plage limitée pour sélectionner la première valeur immédiatement au-dessus de la valeur de test et la première valeur immédiatement en dessous de la valeur de test et choisir celle qui est la plus proche à la valeur test :
(
select the_value
from the_table
where the_value >= 14
order by the_value asc
limit 1
)
union
(
select the_value
from the_table
where the_value < 14
order by the_value desc
limit 1
)
order by abs(the_value - 14)
limit 1