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

MySQLの特定の半径内のクエリポイント

    MySQL5.7以降の場合

    次の簡単な表があるとすると、

    create table example (
      id bigint not null auto_increment primary key,
      lnglat point not null
    );
    
    create spatial index example_lnglat 
        on example (lnglat);
    

    次の簡単なデータで

    insert into example (lnglat) 
    values
    (point(-2.990435, 53.409246)),
    (point(-2.990037, 53.409471)),
    (point(-2.989736, 53.409676)),
    (point(-2.989554, 53.409797)),
    (point(-2.989350, 53.409906)),
    (point(-2.989178, 53.410085)),
    (point(-2.988739, 53.410309)),
    (point(-2.985874, 53.412656)),
    (point(-2.758019, 53.635928));
    

    次のst関数の組み合わせを使用して、別のポイントの特定の範囲内のポイントを取得します(注:ポリゴン内を検索する必要があります)。

    set @px = -2.990497;
    set @py = 53.410943;
    set @range = 150; -- meters
    set @rangeKm = @range / 1000;
    
    set @search_area = st_makeEnvelope (
      point((@px + @rangeKm / 111), (@py + @rangeKm / 111)),
      point((@px - @rangeKm / 111), (@py - @rangeKm / 111))
    );
    
    select id, 
           st_x(lnglat) lng, 
           st_y(lnglat) lat,
           st_distance_sphere(point(@px, @py), lnglat) as distance
      from example
     where st_contains(@search_area, lnglat);
    

    結果として次のようなものが表示されるはずです:

    3   -2.989736   53.409676   149.64084252776277
    4   -2.989554   53.409797   141.93232714661812
    5   -2.98935    53.409906   138.11516275402533
    6   -2.989178   53.410085   129.40289289527473
    

    距離の参考として、制約を削除すると、テストポイントの結果は次のようになります。

    1   -2.990435   53.409246   188.7421181457556
    2   -2.990037   53.409471   166.49406509160158
    3   -2.989736   53.409676   149.64084252776277
    4   -2.989554   53.409797   141.93232714661812
    5   -2.98935    53.409906   138.11516275402533
    6   -2.989178   53.410085   129.40289289527473
    7   -2.988739   53.410309   136.1875540498202
    8   -2.985874   53.412656   360.78532732013963
    9   -2.758019   53.635928   29360.27797292756
    

    注1 :このフィールドはlnglatと呼ばれます。これは、ポイントを(x、y)と考える場合の正しい順序であり、ほとんどの関数(ポイントなど)がパラメーターを受け入れる順序でもあるためです

    注2 :円を使用する場合、実際には空間インデックスを利用できません。また、ポイントフィールドはnullを受け入れるように設定できますが、空間インデックスはnull可能の場合はインデックス付けできません(インデックス内のすべてのフィールドはnull以外である必要があります)。

    注3 :st_bufferは(ドキュメントによって)このユースケースには不適切であると見なされています

    注4 :上記の関数(特にst_distance_sphere)は高速であると文書化されていますが、必ずしも超正確であるとは限りません。データがそれに非常に敏感である場合は、検索に少し小刻みに動く余地を追加し、結果セットに微調整を加えます



    1. リレーショナルオブジェクトの主キーを処理するAndroidレルム

    2. Visual StudioでSSISロードを実行しているときにODBC接続が失敗するのに、パッケージ実行ユーティリティを使用して同じパッケージを実行している場合は失敗するのはなぜですか

    3. 以前の選択に基づいてドロップダウンにデータを入力

    4. SQLite GLOB