Мой совет - сначала попробовать подход, основанный на множествах, и посмотреть, как он работает.
Несколько хороших идей о том, почему можно найти здесь .
Общая стратегия: Для каждого location_id
найдите следующую ближайшую location_id
Некоторые конкретные тактики:
- Использование jpgunter's
GETDISTANCE
(код найден ниже) - Нажмите здесь , чтобы увидеть его код в контексте
- Рассчитать расстояние между всеми значениями
location_id
, используя самостоятельное соединение с таблицей location
- Определить произвольное расстояние, которое «слишком далеко», и исключить все, что находится за пределами этого расстояния
- Это может помочь улучшить производительность
- Выберите наименьшее расстояние от результата
Это стартовый скрипт для самостоятельного соединения с таблицей location
и критериями "слишком далеко" ...
SELECT l1.location_id as l1_location_id
,l1.latitude as l1_latitude
,l1.longitude as l1_longitude
,l2.location_id as l2_location_id
,l2.latitude as l2_latitude
,l2.longitude as l2_longitude
,GETDISTANCE(l1.latitude, l1.longitude, l2.latitude, l2.longitude) as l1_12_distance
FROM location AS l1
JOIN location AS l2 ON l1.location_id <> l2.location_id
WHERE GETDISTANCE(l1.latitude, l1.longitude, l2.latitude, l2.longitude) <= 1000; -- JJAUSSI: arbitrary "too far"
Это функция jpgunter GETDISTANCE...
DELIMITER $$
/*
Takes two latitudes and longitudes in degrees. You could comment out the conversion if you want to pass as radians.
Calculate the distance in miles, change the radius to the earth's radius in km to get km.
*/
DROP FUNCTION IF EXISTS GETDISTANCE$$
CREATE FUNCTION GETDISTANCE
(deg_lat1 FLOAT, deg_lng1 FLOAT, deg_lat2 FLOAT, deg_lng2 FLOAT)
RETURNS FLOAT
DETERMINISTIC
BEGIN
DECLARE distance FLOAT;
DECLARE delta_lat FLOAT;
DECLARE delta_lng FLOAT;
DECLARE lat1 FLOAT;
DECLARE lat2 FLOAT;
DECLARE a FLOAT;
SET distance = 0;
/*Convert degrees to radians and get the variables I need.*/
SET delta_lat = radians(deg_lat2 - deg_lat1);
SET delta_lng = radians(deg_lng2 - deg_lng1);
SET lat1 = radians(deg_lat1);
SET lat2 = radians(deg_lat2);
/*Formula found here: http://www.movable-type.co.uk/scripts/latlong.html*/
SET a = sin(delta_lat/2.0) * sin(delta_lat/2.0) + sin(delta_lng/2.0) * sin(delta_lng/2.0) * cos(lat1) * cos(lat2);
SET distance = 3956.6 * 2 * atan2(sqrt(a), sqrt(1-a));
RETURN distance;
END$$
DELIMITER ;
Возможно, вы захотите пересмотреть имя поля year
, так как оно resошибочное слово .
Вы можете обнаружить, что если / когда ваша база данных увеличивается, эти имена являются слишком общими:
location
address
latitude
longitude
Однако я не знаю вашу базу данных.Возможно, ваши имена таблиц и полей точно соответствуют вашим потребностям.Надеюсь, это поможет!