web-dev-qa-db-ja.com

半径xマイル以内の他の行のmySQL経度と緯度のクエリ

現在、約1万行がデータベースに格納されています。それらのすべては、郵便番号の中心に基づく経度/緯度を持っています。現在拡張を試みているクエリを見つけましたが、全体としてはある程度うまくいきます。ただし、以下の私の例では、半径25マイル以内のものを見つけようとしています。これは、ほとんどの部分でうまくいくようです。ほとんどの結果は25マイルの基準内で収まりますが、マークから86マイルから800マイル離れたところから少し離れているところが少しあります。

例:これは私の中心の緯度/経度です:37.2790669、-121.874722 =カリフォルニア州サンノゼ次のような結果が得られます:33.016928、-116.846046 =カリフォルニア州サンディエゴはサンノゼから約355マイルです。

私の現在のクエリは次のようになります:

SELECT *,(((acos(sin(($lat*pi()/180)) * sin((`latitude`*pi()/180))+cos(($lat*pi()/180))
* cos((`latitude`*pi()/180)) * cos((($lon - `longitude`)*pi()/180))))*180/pi())*60*1.1515)
AS `distance` FROM `geo_locations` HAVING `distance` <= 25 ORDER BY `distance` ASC"
36
chris

これが私が使用する店舗検索で使用するクエリです。

SELECT
    `id`,
    (
        6371 *
        acos(
            cos( radians( :lat ) ) *
            cos( radians( `lat` ) ) *
            cos(
                radians( `long` ) - radians( :long )
            ) +
            sin(radians(:lat)) *
            sin(radians(`lat`))
        )
    ) `distance`
FROM
    `location`
HAVING
    `distance` < :distance
ORDER BY
    `distance`
LIMIT
    25

:latおよび:longはユーザーが渡したポイントで、latlongはデータベースに保存されているポイントです。

:distanceはマイルで測定されます。コードの作業バージョンでは、:distanceは実際には10〜50マイルの範囲のドロップダウンからプルされます

キロメートルで機能するようにコードを変更するには、そのソリューションのjoshhendoを使用して、3959(地球の中心からその表面までの距離(マイル))を6371(3959マイルをキロメートルに換算)に変更します。

98
Gordnfreeman