Mysql
 sql >> база данни >  >> RDS >> Mysql

Намерете всички пощенски кодове в рамките на определено разстояние от пощенски код

Ето нещо, което написах преди доста време, което може да ви насочи в правилната посока.

Докато поискахте VB.Net, това, от което наистина се нуждаете, е заявка, която прави "Great Circle Разстояние " изчисление за определяне на разстоянието между две точки, идентифицирани по географска ширина и дължина.

И така, правейки следните предположения:

  1. Данните за пощенския ви код са в една таблица.
  2. Спомената таблица има атрибути за ширина и дължина, които са приблизителният центроид на пощенския код

Можете да използвате LINQ към SQL заявка, която произвежда желания набор от резултати, като използвате нещо подобно

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

Изглежда сложно, защото е така. Тук в SO има много по-умни хора, които могат да обяснят алгоритъма. Просто внедрих това от някакъв SQL код, който намерих в интернет - не мога да си спомня откъде. Търсене в Google трябва да ви отведе до там.

Първата заявка (zipQry) връща ширината и дължината на началния пощенски код в градуси и радиани. След това тези резултати се използват за изпълнение на втората заявка.

Първата част от клаузата WHERE във втората заявка:

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

Просто стесних списъка с пощенски кодове, които трябва да бъдат разгледани, правейки заявката да се изпълнява много по-бързо. Той добавя произволно количество към ширината и дължината, така че да не проверявате всички пощенски кодове в Охайо, когато търсите радиус в Калифорния. Всичко останало е част от гореспоменатия алгоритъм за голямо кръгово разстояние.

Това вероятно можеше да бъде направено с една заявка за по-голяма ефективност, но имах нужда от това по този начин навремето, причините сега бяха изгубени за мен.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да добавите уникален ключ към съществуваща таблица (с редове, които не са уникални)

  2. Sql избира елементите, съответстващи на масива, и ги показва в ред

  3. jQuery Autocomplete Mysql PHP

  4. MySQL:НЕ ХАРЕСВА

  5. Моля, обяснете MySQL Joins на прост език