Saya pikir pertanyaan Anda mengatakan Anda memiliki city
nilai untuk dua kota yang jaraknya ingin Anda hitung.
Kueri ini akan melakukan pekerjaan untuk Anda, menghasilkan jarak dalam km. Ini menggunakan rumus hukum kosinus bola.
Perhatikan bahwa Anda menggabungkan tabel dengan tabel itu sendiri sehingga Anda dapat mengambil dua pasangan koordinat untuk perhitungan.
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
Perhatikan bahwa konstanta 111.1111
adalah jumlah kilometer per derajat garis lintang, berdasarkan definisi lama Napoleon tentang meter sebagai sepersepuluh ribu jarak dari khatulistiwa ke kutub. Definisi itu cukup dekat untuk pekerjaan pencari lokasi.
Jika Anda menginginkan mil undang-undang alih-alih kilometer, gunakan 69.0
sebagai gantinya.
http://sqlfiddle.com/#!9/21e06/412/0
Jika Anda mencari poin terdekat, Anda mungkin tergoda untuk menggunakan klausa seperti ini:
HAVING distance_in_km < 10.0 /* slow ! */
ORDER BY distance_in_km DESC
Itu (seperti yang kami katakan di dekat Boston MA USA) sangat lambat.
Dalam hal ini Anda perlu menggunakan perhitungan kotak pembatas. Lihat artikel ini tentang cara melakukannya. http://www.plumislandmedia.net/mysql/haversine-mysql- lokasi terdekat/
Rumusnya berisi LEAST()
fungsi. Mengapa? Karena ACOS()
fungsi melempar kesalahan jika argumennya bahkan sedikit lebih besar dari 1. Ketika dua titik yang dipertanyakan sangat berdekatan, ekspresi dengan COS()
dan SIN()
perhitungan terkadang dapat menghasilkan nilai yang sedikit lebih besar dari 1 karena floating-point epsilon (ketidakakuratan
). LEAST(1.0, dirty-great-expression)
panggilan mengatasi masalah itu.
Ada cara yang lebih baik, formula
oleh Thaddeus Vincenty
. Ia menggunakan ATAN2()
daripada ACOS()
sehingga kurang rentan terhadap masalah epsilon.