Una opción sería algo como:
select the_value,
abs(the_value - 14) as distance_from_test
from the_table
order by distance_from_test
limit 1
Para seleccionar un registro aleatorio, puede agregar , rand()
al order by
cláusula. La desventaja de este método es que no obtiene ningún beneficio de los índices porque tiene que ordenar el valor derivado distance_from_test
.
Si tiene un índice en the_value
y relaja su requisito de que el resultado sea aleatorio en el caso de empates, puede realizar un par de consultas de rango limitado para seleccionar el primer valor inmediatamente por encima del valor de prueba y el primer valor inmediatamente por debajo del valor de prueba y elegir el más cercano al valor de prueba:
(
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