Ik denk dat je vraag zegt dat je de city
. hebt waarden voor de twee steden waartussen u de afstand wilt berekenen.
Deze zoekopdracht zal het werk voor u doen en de afstand in km opleveren. Het gebruikt de formule van de sferische cosinuswet.
Merk op dat je de tabel met zichzelf samenvoegt, zodat je twee coördinatenparen voor de berekening kunt ophalen.
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
Merk op dat de constante 111.1111
is het aantal kilometers per breedtegraad, gebaseerd op de oude Napoleontische definitie van de meter als een tienduizendste van de afstand van de evenaar tot de pool. Die definitie is dichtbij genoeg voor locatiezoekerwerk.
Als u mijlen wilt in plaats van kilometers, gebruik dan 69.0
in plaats daarvan.
http://sqlfiddle.com/#!9/21e06/412/0
Als u op zoek bent naar punten in de buurt, kunt u in de verleiding komen om een clausule als volgt te gebruiken:
HAVING distance_in_km < 10.0 /* slow ! */
ORDER BY distance_in_km DESC
Dat is (zoals we zeggen in de buurt van Boston MA USA) wicked slow.
In dat geval moet u een begrenzingsvakberekening gebruiken. Zie dit artikel over hoe dat te doen. http://www.plumislandmedia.net/mysql/haversine-mysql- dichtstbijzijnde-loc/
De formule bevat een LEAST()
functie. Waarom? Omdat de ACOS()
functie geeft een fout als zijn argument zelfs iets groter is dan 1. Wanneer de twee punten in kwestie heel dicht bij elkaar liggen, wordt de uitdrukking met de COS()
en SIN()
berekeningen kunnen soms een waarde opleveren die iets groter is dan 1 vanwege floating-point epsilon (onnauwkeurigheid
). De LEAST(1.0, dirty-great-expression)
oproep lost dat probleem op.
Er is een betere manier, een formule
door Thaddeus Vincenty
. Het gebruikt ATAN2()
in plaats van ACOS()
dus het is minder vatbaar voor epsilon-problemen.