Anda hanya perlu melakukan self-join. Bergabung tabel adalah sangat bagian mendasar dari SQL—Anda benar-benar harus membacanya sebelum mencoba memahami jawaban ini lebih lanjut.
SELECT poi.asciiname,
suburb.asciiname,
suburb.country,
DEGREES(
ACOS(
SIN(RADIANS( poi.latitude))
* SIN(RADIANS(suburb.latitude))
+ COS(RADIANS( poi.latitude))
* COS(RADIANS(suburb.latitude))
* COS(RADIANS(poi.longitude - suburb.longitude))
)
) * 60 * 1.852 AS distance
FROM geoname AS poi
JOIN geoname AS suburb
WHERE poi.asciiname IN ('Tamworth', 'Birmingham', 'Roanoke')
AND poi.population > 0
AND poi.fcode = 'PPL'
AND suburb.fcode IN ('PPLX', 'PPPL')
HAVING distance <= 60
ORDER BY poi.asciiname, distance
Lihat di sqlfiddle .
Anda akan melihat bahwa saya telah menggunakan IN()
operator sebagai singkatan dari value = A OR value = B OR ...
.
Anda juga akan memperhatikan bahwa saya telah menggunakan DEGREES()
dan RADIANS()
fungsi daripada mencoba melakukan konversi tersebut secara eksplisit.
Anda kemudian mengalikan menit lintang dengan faktor 1.851999999962112
, yang agak aneh:sangat dekat dengan 1.852
, yang merupakan jumlah tepat kilometer dalam satu mil laut (secara historis didefinisikan sebagai satu menit garis lintang), namun sedikit berbeda—saya berasumsi Anda bermaksud menggunakannya.
Terakhir, Anda memiliki nilai literal yang digunakan untuk memfilter jarak dalam kumpulan hasil sebagai string, yaitu '60'
, padahal jelas ini adalah nilai numerik dan harus diberi tanda kutip.