sql >> Databáze >  >> RDS >> Mysql

Najděte všechna PSČ v zadané vzdálenosti od PSČ

Zde je něco, co jsem napsal před chvílí, co vás může navést správným směrem.

Zatímco jste se ptali na VB.Net, skutečně potřebujete dotaz, který udělá „Velký kruh Vzdálenost " výpočet k určení vzdálenosti mezi dvěma body určenými zeměpisnou šířkou a délkou.

Takže za následujících předpokladů:

  1. Údaje o PSČ jsou v jediné tabulce.
  2. Tabulka má atributy pro zeměpisnou šířku a délku, které jsou přibližným těžištěm PSČ

Můžete použít dotaz LINQ to SQL, který vytvoří požadovanou sadu výsledků pomocí něčeho takového

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

Vypadá to složitě, protože to tak je. Na SO jsou mnohem chytřejší lidé, kteří dokážou vysvětlit algoritmus. Implementoval jsem to pouze z nějakého kódu SQL, který jsem našel na internetu - nemohu si vzpomenout odkud. Vyhledávání Google by vás tam mělo dostat.

První dotaz (zipQry) vrací zeměpisnou šířku a délku počátečního PSČ ve stupních i radiánech. Tyto výsledky se pak použijí k provedení druhého dotazu.

První část klauzule WHERE ve druhém dotazu:

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

Právě jsme zúžili seznam PSČ, která mají být prozkoumána, takže dotaz běží mnohem rychleji. Přidává libovolnou částku k zeměpisné šířce a délce, takže při hledání okruhu v Kalifornii nekontrolujete všechna PSČ v Ohiu. Zbytek je součástí výše zmíněného algoritmu Great Circle Distance.

Pravděpodobně by to bylo možné provést v rámci jednoho dotazu pro větší efektivitu, ale v té době jsem to tímto způsobem potřeboval, důvody mi teď zmizely.



  1. Jak napsat dotaz SQL pro výběr a seskupení podle typu a počtu podle typu?

  2. Volání REST API ze spouštěče nebo uložené procedury v mysql?

  3. Pokuste se znovu otevřít již uzavřený objekt sqlitedatabase

  4. Jak používat modely django s cizími klíči v různých databázích?