勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

MySQLで経度緯度から半径○Kmのデータを抽出する方法

   2024/01/13  MySQL

経度と緯度をtext型として格納しているMySQLのテーブルがあり、指定した経度緯度から半径○kmのデータ一覧を抽出したかった。以下に方法をメモ。

 

ソース

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
$km = 1; //半径km。半径500mを出したい場合は0.5にする
$sql = '
SELECT
*,
(6371 * ACOS(
COS(RADIANS(緯度))
* COS(RADIANS(lat))
* COS(RADIANS(`long`) - RADIANS(経度))
+ SIN(RADIANS(緯度))
* SIN(RADIANS(lat))
)) AS distance
FROM
table
WHERE status = 1
HAVING
distance <= ' . $km . '
ORDER BY
distance
';
$km = 1; //半径km。半径500mを出したい場合は0.5にする $sql = ' SELECT *, (6371 * ACOS( COS(RADIANS(緯度)) * COS(RADIANS(lat)) * COS(RADIANS(`long`) - RADIANS(経度)) + SIN(RADIANS(緯度)) * SIN(RADIANS(lat)) )) AS distance FROM table WHERE status = 1 HAVING distance <= ' . $km . ' ORDER BY distance ';
$km = 1; //半径km。半径500mを出したい場合は0.5にする
$sql = '
    SELECT
    *, 
    (6371 * ACOS(
        COS(RADIANS(緯度))
        * COS(RADIANS(lat))
        * COS(RADIANS(`long`) - RADIANS(経度))
        + SIN(RADIANS(緯度))
        * SIN(RADIANS(lat))
    )) AS distance
    FROM
        table
    WHERE status = 1 
    HAVING
        distance <= ' . $km . ' 
    ORDER BY
        distance
';

SQL文内のlongを`(アクサングラーブ)で囲んでいるのは予約語に当たるため。

 

その他

最初は経度と緯度から0.001ずつぐらい引いたり足したりして抽出したけどかなり位置情報が偏った。今回の方法はきっちりと指定した経度緯度を中心に抽出できた。

尚、経度緯度をMySQLで扱う場合はfloatやtextではなくgeometryを使うのが良いっぽい。

 

参考サイト

https://www.firstlogic.co.jp/blog/lab/raku/71

http://blog.asial.co.jp/473

 

予約語

https://dev.mysql.com/doc/refman/5.6/ja/reserved-words.html

 - MySQL

  関連記事

MySQLでINSERT時にオートインクリメントではないカラムに連番を登録する方法

MySQLでINSERT時にオートインクリメントではないカラムに連番を登録したい ...

MySQLにてSELECT時にdate型のカラムから干支(十二支)を計算し表示する方法

MySQLにdate型のカラムに誕生年月日が格納されており、そこから干支(十二支 ...

MySQLで検索した件数の取得

ページングとかで必要になる総件数について、 いつもググってしまっていたのでメモ。 ...

htmlspecialcharsを通してMySQLに格納したものを元に戻して出力

MySQLにHTMLタグを入れたくない場合にhtmlspecialcharsを使 ...

MySQLでデータがあれば上書き、無ければ挿入する

既存のソースを編集時に「REPLACE INTO~~」 という見たことの無いSQ ...

S