Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Các điểm truy vấn trong bán kính nhất định trong MySQL

Đối với MySQL 5.7+

Cho chúng ta có bảng đơn giản sau,

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

create spatial index example_lnglat 
    on example (lnglat);

Với dữ liệu đơn giản sau,

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

Bạn sẽ nhận được các điểm trong một phạm vi nhất định của một điểm khác (lưu ý:chúng ta phải tìm kiếm bên trong một đa giác) với sự kết hợp của các hàm st sau:

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

Kết quả là bạn sẽ thấy một cái gì đó như thế này:

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

Để tham khảo về khoảng cách, nếu chúng ta loại bỏ ràng buộc, kết quả cho điểm kiểm tra sẽ giống như sau:

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

Lưu ý 1 :trường được gọi là lnglat vì đó là thứ tự chính xác nếu bạn coi các điểm là (x, y) và cũng là thứ tự mà hầu hết các hàm (như point) chấp nhận tham số

Lưu ý 2 :bạn thực sự không thể tận dụng chỉ mục không gian nếu bạn sử dụng các vòng kết nối; cũng lưu ý rằng trường điểm có thể được đặt để chấp nhận null nhưng các chỉ mục không gian không thể lập chỉ mục nó nếu nó có thể là null (tất cả các trường trong chỉ mục được yêu cầu không phải là null).

Lưu ý 3 :st_buffer được coi là (theo tài liệu) là không tốt cho trường hợp sử dụng này

Lưu ý 4 :các hàm trên (cụ thể là st_distance_sphere) được ghi lại là nhanh nhưng không nhất thiết phải siêu chính xác; nếu dữ liệu của bạn siêu nhạy cảm, hãy thêm một chút khoảng trống cho tìm kiếm và thực hiện một số tinh chỉnh đối với tập kết quả



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các mối quan hệ hùng hồn đối với vấn đề di cư ở nước ngoài trong Laravel

  2. Cảnh báo:mysql_result () mong đợi tham số 1 là tài nguyên, boolean đã cho

  3. THÔNG TIN DỮ LIỆU TẢI MySQL:hoạt động, nhưng bộ kết thúc dòng không thể đoán trước

  4. mysql tìm id nhỏ nhất + duy nhất có sẵn

  5. Truy vấn SCHEMA THÔNG TIN của MySQL:Tại sao? Thế nào?