Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Pencarian spasial Oracle dalam jarak jauh

Anda memiliki referensi yang cukup bagus untuk pencarian jarak jauh mySQL.

Lupakan hal-hal Oracle Spasial. Terlalu banyak kode, terlalu banyak kerumitan, tidak cukup nilai tambah.

Inilah kueri yang akan melakukan trik. Ini menggunakan jarak dalam mil undang-undang. EDIT Ini memperbaiki bug yang disebutkan oleh mdarwin, dengan biaya pemeriksaan terpisah jika Anda mencoba menggunakannya untuk lokasi di kutub utara atau selatan.

  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

Jika Anda bekerja dalam kilometer, ubah mydst/69 menjadi mydst/111.045, dan ubah 3959 menjadi 6371,4. (1/69 mengubah mil ke derajat; 3959 adalah nilai jari-jari planet.)

Sekarang, Anda mungkin tergoda untuk menggunakan kueri besar ini sebagai "kotak hitam ajaib". Jangan lakukan itu! Ini tidak terlalu sulit untuk dipahami, dan jika Anda memahaminya, Anda akan dapat melakukan pekerjaan yang lebih baik. Inilah yang terjadi.

Klausa ini adalah inti dari apa yang membuat kueri menjadi cepat. Ini mencari tabel Kota Anda untuk kota-kota terdekat ke titik yang Anda tentukan.

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

Agar berfungsi, Anda pasti membutuhkan indeks pada kolom LATITUDE Anda. Indeks pada kolom LONGITUDE Anda juga akan sedikit membantu. Itu melakukan pencarian perkiraan, mencari baris yang berada dalam patch kuasi-persegi panjang di permukaan bumi dekat titik Anda. Ini memilih terlalu banyak kota, tetapi tidak terlalu banyak.

Klausa ini di sini memungkinkan Anda menghilangkan kota tambahan dari kumpulan hasil Anda:

   WHERE distance <= mydst

Klausa ini adalah rumus haversine yang menghitung jarak lingkaran besar antara setiap kota dan titik Anda.

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

Klausa ini memungkinkan Anda memasukkan titik Anda, dan batas radius Anda, sekali saja sebagai variabel terikat ke kueri Anda. Ini membantu karena berbagai rumus menggunakan variabel tersebut beberapa kali.

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

Sisa kueri hanya mengatur hal-hal sehingga Anda memilih dan memesan berdasarkan jarak.

Berikut penjelasan lebih lengkapnya:http://www.plumislandmedia.net /mysql/haversine-mysql-nearest-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. Periksa batasan pada jenis

  2. Cara Menginstal SQLcl di Mac

  3. Batasi ConnectionTimeout untuk Oracle Database

  4. Kompiler pro*C Oracle dan gnu C (__builtin_va_list, __attribute__, dll)

  5. Permintaan Pembaruan Oracle SQL membutuhkan waktu berhari-hari untuk diperbarui