Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie o punkty w danym promieniu w MySQL

Dla MySQL 5.7+

Biorąc pod uwagę następującą prostą tabelę,

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

create spatial index example_lnglat 
    on example (lnglat);

Z następującymi prostymi danymi,

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));

Otrzymasz punkty w danym zakresie innego punktu (uwaga:musimy szukać wewnątrz wielokąta) z następującą kombinacją funkcji 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);

W rezultacie powinieneś zobaczyć coś takiego:

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

Dla odniesienia na odległość, jeśli usuniemy ograniczenie, wynik dla punktu testowego wygląda tak:

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

Uwaga 1 :pole nazywa się lnglat, ponieważ jest to poprawna kolejność, jeśli myślisz o punktach jako (x, y) i jest to również kolejność, w której większość funkcji (takich jak punkt) akceptuje parametr

Uwaga 2 :nie możesz właściwie korzystać z indeksów przestrzennych, jeśli używasz okręgów; zauważ również, że pole punktowe może być ustawione tak, aby akceptowało wartość null, ale indeksy przestrzenne nie mogą go indeksować, jeśli jest dopuszczalna (wszystkie pola w indeksie muszą być różne od wartości null).

Uwaga 3 :st_buffer jest uważany (według dokumentacji) za zły w tym przypadku użycia

Uwaga 4 :powyższe funkcje (w szczególności st_distance_sphere) są udokumentowane jako szybkie, ale niekoniecznie super dokładne; jeśli twoje dane są na to bardzo wrażliwe, dodaj trochę miejsca na wyszukiwanie i dostosuj zestaw wyników



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jakie jest znaczenie <> w zapytaniu mysql?

  2. MySQL Group By, aby wyświetlić najnowsze wyniki

  3. Zastąpienie PATINDEX() w MYSQL

  4. spraw, aby wszystkie liczby całkowite z automatycznym przyrostem miały taką samą liczbę cyfr z wiodącymi zerami

  5. Kalendarz PHP z powtarzającymi się wydarzeniami z bazy danych MySQL