sql >> データベース >  >> RDS >> Mysql

mysqlで緯度と経度を使用して2点間の距離を検索します

    あなたの質問はあなたが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) 通話はその問題に対処します。

    より良い方法があります。数式 Thaddeus Vincenty ATAN2()を使用します ACOS()ではなく そのため、イプシロンの問題の影響を受けにくくなります。



    1. カスケード削除制約を追加するにはどうすればよいですか?

    2. GTIDモードでMySQLの開始時間が遅いですか?バイナリログファイルのサイズが問題になる可能性があります

    3. PostgreSQLでpgBouncerを使用するためのガイド

    4. ハングしたクエリを終了します(トランザクションでアイドル状態)