Jag tror att din fråga säger att du har city
värden för de två städerna mellan vilka du vill beräkna avståndet.
Denna fråga kommer att göra jobbet åt dig och ger avståndet i km. Den använder den sfäriska cosinuslagformeln.
Lägg märke till att du kopplar tabellen till sig själv så att du kan hämta två koordinatpar för beräkningen.
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
Lägg märke till att konstanten 111.1111
är antalet kilometer per latitud, baserat på den gamla Napoleon-definitionen av mätaren som en tiotusendel av avståndet från ekvatorn till polen. Den definitionen är tillräckligt nära för platssökningsarbete.
Om du vill ha lagstadgade miles istället för kilometer, använd 69.0
istället.
http://sqlfiddle.com/#!9/21e06/412/0
Om du letar efter närliggande punkter kan du bli frestad att använda en klausul ungefär så här:
HAVING distance_in_km < 10.0 /* slow ! */
ORDER BY distance_in_km DESC
Det är (som vi säger nära Boston MA, USA) grymt långsamt.
I så fall måste du använda en bounding box-beräkning. Se den här texten om hur du gör det. http://www.plumislandmedia.net/mysql/haversine-mysql- närmaste-loc/
Formeln innehåller en LEAST()
fungera. Varför? Eftersom ACOS()
funktionen ger ett fel om dess argument till och med är något större än 1. När de två punkterna i fråga är mycket nära varandra kommer uttrycket med COS()
och SIN()
beräkningar kan ibland ge ett värde som är något större än 1 på grund av floating-point epsilon (oexakthet
). LEAST(1.0, dirty-great-expression)
call hanterar det problemet.
Det finns ett bättre sätt, en formel
av Thaddeus Vincenty
. Den använder ATAN2()
snarare än ACOS()
så det är mindre mottagligt för epsilon-problem.