あなたの質問はあなたがcity
を持っていると言っていると思います 距離を計算する2つの都市の値。
このクエリはあなたに代わって仕事をし、距離をkm単位で算出します。球面余弦定理の公式を使用しています。
テーブルをそれ自体に結合して、計算のために2つの座標ペアを取得できることに注意してください。
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
に注意してください は、赤道から極までの距離の1万分の1としてのメーターの古いナポレオンの定義に基づく、緯度1度あたりのキロメートル数です。その定義は、ロケーションファインダーの作業に十分に近いものです。
キロメートルではなく法定マイルが必要な場合は、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-最寄-loc/
数式にはLEAST()
が含まれています 働き。なんで? ACOS()
関数の引数が1より少しでも大きい場合、関数はエラーをスローします。問題の2つのポイントが非常に接近している場合、COS()
を使用した式 およびSIN()
浮動小数点イプシロン(不正確
)が原因で、計算によって1よりわずかに大きい値が生成される場合があります。 )。 LEAST(1.0, dirty-great-expression)
通話はその問題に対処します。
より良い方法があります。ATAN2()
を使用します ACOS()
ではなく そのため、イプシロンの問題の影響を受けにくくなります。