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

Tìm kiếm không gian Oracle trong khoảng cách

Bạn có một tài liệu tham khảo khá tốt ở đó để tìm kiếm khoảng cách mySQL.

Quên những thứ về Oracle Spatial. Quá nhiều mã, quá nhiều phức tạp, không đủ giá trị gia tăng.

Đây là một truy vấn sẽ thực hiện thủ thuật. Điều này sử dụng khoảng cách tính bằng dặm theo quy chế. CHỈNH SỬA Điều này sẽ sửa lỗi được mdarwin đề cập, với chi phí là kiểm tra phân chia nếu bạn cố gắng sử dụng nó cho một vị trí ở cực bắc hoặc cực nam.

  SELECT id, city, LATITUDE, LONGITUDE, distance
    FROM
  (
    SELECT id, 
           city, 
           LATITUDE, LONGITUDE,
           (3959 * ACOS(COS(RADIANS(LATITUDE)) 
                 * COS(RADIANS(mylat)) 
                 * COS(RADIANS(LONGITUDE) - RADIANS(mylng)) 
                 + SIN(RADIANS(LATITUDE)) 
                 * SIN(RADIANS(mylat)) 
               ))
           AS distance,
           b.mydst
      FROM Cities
      JOIN (
        SELECT :LAT AS mylat,
               :LONG AS mylng,
               :RADIUS_LIMIT AS mydst
          FROM DUAL
      )b ON (1 = 1)
     WHERE LATITUDE >=  mylat -(mydst/69)
       AND LATITUDE <=  mylat +(mydst/69)
       AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
       AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))
  )a
   WHERE distance <= mydst
   ORDER BY distance

Nếu bạn đang làm việc theo km, hãy thay đổi mydst / 69 thành mydst / 111.045 và thay đổi 3959 thành 6371.4. (1/69 chuyển đổi dặm thành độ; 3959 là một giá trị cho bán kính của hành tinh.)

Bây giờ, bạn có thể bị cám dỗ để sử dụng truy vấn lớn này như một "hộp đen ma thuật". Đừng làm điều đó! Nó không quá khó hiểu, và nếu bạn hiểu nó, bạn sẽ có thể hoàn thành công việc tốt hơn. Đây là những gì đang xảy ra.

Mệnh đề này là trọng tâm của những gì làm cho truy vấn nhanh chóng. Nó tìm kiếm bảng Thành phố của bạn cho các thành phố lân cận đến điểm bạn đã chỉ định.

     WHERE LATITUDE >=  mylat -(mydst/69)
       AND LATITUDE <=  mylat +(mydst/69)
       AND LONGITUDE >= mylng -(mydst/(69 * COS(RADIANS(mylat))))
       AND LONGITUDE <= mylng +(mydst/(69 * COS(RADIANS(mylat))))

Để nó hoạt động, bạn chắc chắn cần một chỉ mục trên cột LATITUDE của mình. Chỉ mục trên cột LONGITUDE của bạn cũng sẽ hữu ích một chút. Nó thực hiện một tìm kiếm gần đúng, tìm kiếm các hàng nằm trong một mảnh bán hình chữ nhật trên bề mặt trái đất gần điểm của bạn. Nó chọn quá nhiều thành phố, nhưng không quá nhiều.

Điều khoản này ở đây cho phép bạn loại bỏ các thành phố thừa khỏi tập kết quả của bạn:

   WHERE distance <= mydst

Mệnh đề này là công thức hasrsine tính toán khoảng cách vòng tròn lớn giữa mỗi thành phố và điểm của bạn.

           (3959 * ACOS(COS(RADIANS(LATITUDE)) 
                 * COS(RADIANS(mylat)) 
                 * COS(RADIANS(LONGITUDE) - RADIANS(mylng)) 
                 + SIN(RADIANS(LATITUDE)) 
                 * SIN(RADIANS(mylat)) 

Mệnh đề này cho phép bạn nhập điểm và giới hạn bán kính của bạn, chỉ một lần dưới dạng các biến liên kết với truy vấn của bạn. Nó hữu ích vì các công thức khác nhau sử dụng các biến đó nhiều lần.

        SELECT :LAT AS mylat,
               :LONG AS mylng,
               :RADIUS_LIMIT AS mydst
          FROM DUAL

Phần còn lại của truy vấn chỉ đơn giản là sắp xếp mọi thứ để bạn chọn và sắp xếp theo khoảng cách.

Đây là lời giải thích đầy đủ hơn: http://www.plumislandmedia.net / mysql / haversine-mysql-near-loc /



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sử dụng ROWID để định vị Hàng / Bản ghi trong Oracle có an toàn không?

  2. Di chuyển biểu mẫu Oracle dựa trên ký tự

  3. Cách thực thi tập lệnh sql Oracle thông qua mã java

  4. Tôi tiếp tục gặp lỗi trong quy trình của mình giúp thêm khóa học mới và tôi đã đưa các yêu cầu vào phần mô tả

  5. Không thể truy cập máy chủ Oracle 12c từ máy tính từ xa bằng nhà cung cấp .Net