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

Tìm tất cả các Zipcode trong khoảng cách được chỉ định của một mã zipcode

Đây là điều mà tôi đã viết khá lâu có thể giúp bạn đi đúng hướng.

Trong khi bạn yêu cầu VB.Net, những gì bạn thực sự cần là một truy vấn thực hiện " Vòng kết nối tuyệt vời Khoảng cách "tính toán để xác định khoảng cách giữa hai điểm được xác định theo vĩ độ và kinh độ.

Vì vậy, đưa ra các giả định sau:

  1. Dữ liệu mã zip của bạn nằm trong một bảng.
  2. Bảng đã nói có các thuộc tính cho vĩ độ và kinh độ là tâm gần đúng của mã zip

Bạn có thể sử dụng truy vấn LINQ to SQL để tạo ra tập kết quả mong muốn bằng cách sử dụng thứ gì đó như thế này

Const EARTH_RADIUS As Single = 3956.0883313286095
Dim radCvtFactor As Single = Math.PI / 180
Dim zipCodeRadius As Integer = <Your Radius Value>

Dim zipQry = From zc In db.ZipCodes 
             Where zc.Zip = "<Your Zip Code>" _
             Select zc.Latitude, 
                    zc.Longitude, 
                    ZipLatRads = RadCvtFactor * zc.Latitude, 
                    ZipLonRads = RadCvtFactor * zc.Longitude
Dim zipRslt = zipQry.SingleOrDefault()
If zipRslt IsNot Nothing Then
    Dim zcQry = From zc In db.ZipCodes _
                Where zc.Latitude >= (zipRslt.Latitude - 0.5) And zc.Latitude <= (zipRslt.Latitude + 0.5) _
                And zc.Longitude >= (zipRslt.Longitude - 0.5) And (zc.Longitude <= zipRslt.Longitude + 0.5) _
                And Math.Abs(EARTH_RADIUS * (2 * Math.Atan2(Math.Sqrt(Math.Pow(Math.Sin(((RadCvtFactor * zc.Latitude) - zipRslt.ZipLatRads) / 2), 2) + _
                Math.Cos(zipRslt.ZipLatRads) * Math.Cos(RadCvtFactor * zc.Latitude) * _
                Math.Pow(Math.Sin(((RadCvtFactor * zc.Longitude) - zipRslt.ZipLonRads) / 2), 2)), _
                Math.Sqrt(1 - Math.Pow(Math.Sin(((RadCvtFactor * zc.Latitude) - zipRslt.ZipLatRads) / 2), 2) + _
                Math.Cos(zipRslt.ZipLatRads) * Math.Cos(RadCvtFactor * zc.Latitude) * _
                Math.Pow(Math.Sin((RadCvtFactor * zc.Longitude) / 2), 2))))) <= zipCodeRadius _
                Select zc
End If

Nó trông phức tạp, bởi vì nó là. Có rất nhiều người thông minh hơn ở đây trên SO có thể giải thích thuật toán. Tôi chỉ thực hiện điều này từ một số mã SQL mà tôi tìm thấy trên internet - tôi không thể nhớ lại từ đâu. Tìm kiếm của Google sẽ đưa bạn đến đó.

Truy vấn đầu tiên (zipQry) trả về vĩ độ và vĩ độ của mã zip bắt đầu theo cả độ và radian. Sau đó, các kết quả này được sử dụng để thực hiện truy vấn thứ hai.

Phần đầu tiên của mệnh đề WHERE trong truy vấn thứ hai:

Where zc.Latitude >= (zipRslt.Latitude - 0.5) And zc.Latitude <= (zipRslt.Latitude + 0.5) _
And zc.Longitude >= (zipRslt.Longitude - 0.5) And (zc.Longitude <= zipRslt.Longitude + 0.5) _

Chỉ cần thu hẹp danh sách mã zip cần kiểm tra, làm cho truy vấn chạy nhanh hơn nhiều. Nó thêm một số lượng tùy ý vào vĩ độ và kinh độ để bạn không phải kiểm tra tất cả các mã zip ở Ohio khi tìm kiếm bán kính ở California. Phần còn lại là tất cả các phần của thuật toán Khoảng cách vòng tròn lớn nói trên.

Điều này có thể được thực hiện trong một truy vấn để đạt hiệu quả cao hơn, nhưng tôi cần nó theo cách này vào thời điểm đó, lý do bây giờ tôi đã thua.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hàm PHP chỉ hoạt động một lần

  2. Thứ tự xóa với các ràng buộc khóa ngoại,

  3. Chèn dữ liệu bằng mảng đa chiều từ nhiều trường

  4. Làm thế nào để kiểm tra xem truy vấn MySQL có hợp lệ hay không mà không cần thực thi nó?

  5. Kết nối DSN-less với máy chủ mysql trong ms-access không nhớ tên người dùng và mật khẩu