Мисля, че вашият въпрос казва, че имате city
стойности за двата града, между които искате да изчислите разстоянието.
Тази заявка ще свърши работа вместо вас, като ще даде разстоянието в км. Използва формулата за сферичен косинус.
Забележете, че присъединявате таблицата към нея, за да можете да извлечете две координатни двойки за изчислението.
SELECT a.city AS from_city, b.city AS to_city,
111.111 *
DEGREES(ACOS(LEAST(1.0, COS(RADIANS(a.Latitude))
* COS(RADIANS(b.Latitude))
* COS(RADIANS(a.Longitude - b.Longitude))
+ SIN(RADIANS(a.Latitude))
* SIN(RADIANS(b.Latitude))))) AS distance_in_km
FROM city AS a
JOIN city AS b ON a.id <> b.id
WHERE a.city = 3 AND b.city = 7
Забележете, че константата 111.1111
е броят на километри на градус географска ширина, базиран на старата наполеонова дефиниция на метъра като една десет хилядна от разстоянието от екватора до полюса. Това определение е достатъчно близко за работа с търсене на местоположение.
Ако искате статутни мили вместо километри, използвайте 69.0
вместо това.
http://sqlfiddle.com/#!9/21e06/412/0
Ако търсите близки точки, може да се изкушите да използвате клауза, подобна на това:
HAVING distance_in_km < 10.0 /* slow ! */
ORDER BY distance_in_km DESC
Това е (както казваме близо до Бостън, Масачузетс, САЩ) е много бавно.
В този случай трябва да използвате изчисление на ограничаваща кутия. Вижте тази статия за това как да направите това. http://www.plumislandmedia.net/mysql/haversine-mysql- най-близкото местоположение/
Формулата съдържа LEAST()
функция. Защо? Тъй като ACOS()
функцията издава грешка, ако нейният аргумент е дори малко по-голям от 1. Когато двете въпросни точки са много близо една до друга, изразът с COS()
и SIN()
изчисленията понякога могат да дадат стойност малко по-голяма от 1 поради епсилон с плаваща запетая (неточност
). LEAST(1.0, dirty-great-expression)
обаждането се справя с този проблем.
Има по-добър начин, формула
от Тадеус Винсентий
. Той използва ATAN2()
вместо ACOS()
така че е по-малко податливо на проблеми с епсилон.