Ваше требование все еще не выполнено, если вы хотите получить предсказуемые результаты. Вы призываете выбрать только один ряд из нескольких. Почему желаемый результат показывает id = 3, а не id = 4? Я думаю, вы выбрали один из двух случайным образом.
Этот запрос (https://www.db-fiddle.com/f/USMrhc8gLcRD2rAmuzYzH/0) сделает это за вас.
SET @lat := 26.120888;
SET @long := 85.364832;
SELECT ANY_VALUE(supplier_id), variant_id, ANY_VALUE(price)
FROM ( SELECT ID,
(6371 * acos(cos(radians(@lat)) * cos(radians(lat)) *
cos( radians(lng) - radians(@long)) + sin(radians(@lat)) *
sin(radians(lat)))) AS distance
FROM supplier_products
) t WHERE distance < serving_radius
GROUP BY variant_id
У него есть подзапрос, который нужно показать вариант вашей таблицы, который показывает расстояния от предоставленных значений @lat и @long. Он показывает ID и расстояние. Это оно. (https://www.db-fiddle.com/f/guagWYVXXaf7cPkbojj9KD/2)
SELECT *,
(6371 * acos(cos(radians(@lat)) * cos(radians(lat)) *
cos( radians(lng) - radians(@long)) + sin(radians(@lat)) *
sin(radians(lat)))) AS distance
FROM supplier_products
Затем он использует этот подзапрос во внешнем запросе с GROUP BY, см. Выше.
Но, поскольку вам нужен только один строка за вариант, и вы не сказали нам, как выбрать эту строку, если имеется несколько строк, запрос использует функцию ANY_VALUE () , чтобы выбрать одно из доступных значений для каждого столбца в вашем результате.
Версии MySQL старше 8.0 не нуждаются в функциях ANY_VALUE (), потому что из-за пресловутой нестандартной обработки GROUP 10 * GROUP *: , пожалуйста, прочтите это.
Осторожно: если вы разрешите MySQL использовать этот ANY_VALUE () материал, будь то явный или неявный, вы сведете ваших тестеров и пользователей с ума. Сегодня они иногда получают другие результаты, чем на прошлой неделе, и они удивляются, что они сделали не так. Пожалуйста, не делайте этого.
И еще одна вещь: ваша формула расстояния известна тем, что выбрасывает исключения на очень малых расстояниях. Убедитесь, что он никогда не пытается использовать ACOS () со значением больше 1, изменив его так, чтобы он использовал LEAST (). (https://www.db-fiddle.com/f/USMrhc8gLcRD2rAmuzYzH/1)
(6371 * acos(LEAST(1.0,cos(radians(@lat)) * cos(radians(lat)) *
cos( radians(lng) - radians(@long)) + sin(radians(@lat)) *
sin(radians(lat)))))