2017-04-11 76 views
0

我正在查找SQL查詢以讓我檢索特定半徑內的ZipCodes。特定半徑內的郵編

我有一個名爲tblZip的表,其列爲:Zipcode,Lat(緯度),Long(經度)。

tblZip 

Zipcode | Lat | Long 
Short Text | Number | Number 

我已經檢查了一些其他的答案是建議使用Great-circle Distance但我似乎不明白它是如何工作的。我只是看到所有的轉換成弧度和度數而頭痛,我真的很想理解它,但是我對數學很不好。

我感謝您的幫助和指導。

PS:我正在使用Microsoft Access數據庫。

+0

你會被計算兩條記錄之間或一條記錄與任意點之間的距離?如果前者,那麼你如何選擇這兩點? – toonice

+0

我正在計算特定記錄與表tblZip中所有其他記錄之間的距離。 –

回答

3

考慮在VBA函數中使用半正向公式(借用here)。然後讓它在你的SQL查詢中調用。甚至可以按照您的需求通​​過WHERE條款按距離過濾您的查詢。請注意:此解決方案僅適用於MSAccess.exe程序。您將無法通過ODBC/OLEDB從外部調用它。

而且由於您需要比較地理編碼,因此下面的SQL查詢使用交叉連接,其中每個記錄都與表中的每個其他記錄進行比較。另外,查詢避免了反向重複和相同匹配的配對,從而減小了大小。但是,如果表格很大,因爲交叉連接對自我返回N 記錄,即在重複過濾之前。

SQL

SELECT z1.Zipcode, z2.Zipcode, 
     GetDistance(z1.Lat, z1.Lon, z2.Lat, z2.Lon) As km_distance 
FROM tblZip z1, tblZip z2 
WHERE z1.Zipcode > z2.Zipcode 
AND GetDistance(s1.lat, s1.lon, s1.lat, s2.lon) <= 5; 

VBA(具有5 km或更小距離郵政編碼配對)(獨立模塊中保存)

Function GetDistance(lat1Degrees As Double, lon1Degrees As Double, lat2Degrees As Double, lon2Degrees As Double) As Double 

    Dim earthSphereRadiusKilometers As Double 
    Dim kilometerConversionToMilesFactor As Double 
    Dim lat1Radians As Double 
    Dim lon1Radians As Double 
    Dim lat2Radians As Double 
    Dim lon2Radians As Double 
    Dim AsinBase As Double 
    Dim DerivedAsin As Double 

    'Mean radius of the earth (replace with 3443.89849 to get nautical miles) 
    earthSphereRadiusKilometers = 6371 

    'Convert kilometers into miles (replace 0.621371 with 1 to keep in kilometers) 
    kilometerConversionToMilesFactor = 0.621371 

    'Convert each decimal degree to radians 
    lat1Radians = (lat1Degrees/180) * (4 * ATN(1)) 
    lon1Radians = (lon1Degrees/180) * (4 * ATN(1)) 
    lat2Radians = (lat2Degrees/180) * (4 * ATN(1)) 
    lon2Radians = (lon2Degrees/180) * (4 * ATN(1)) 

    AsinBase = Sin(Sqr(Sin((lat1Radians - lat2Radians)/2)^2 + Cos(lat1Radians) * Cos(lat2Radians) * Sin((lon1Radians - lon2Radians)/2)^2)) 
    DerivedAsin = (AsinBase/Sqr(-AsinBase * AsinBase + 1)) 

    'Get distance from [lat1,lon1] to [lat2,lon2] 
    GetMiles = Round(2 * DerivedAsin * (earthSphereRadiusKilometers * kilometerConversionToMilesFactor), 2) 

End Function 
+0

非常感謝您的詳細解答。它正是我想要的。但是,計算結果並不準確。例如,我嘗試了兩個郵編「00501」和「00705」,GetMiles函數爲我提供了1628.4英里的數據,而很少有在線工具可以計算郵政編碼之間的距離,爲我提供了1619.2和1617.87。你有什麼想法如何獲得更精確的結果? –

+0

可能是由於pi小數精度。嘗試用'(4 * ATN(1))'改變3.14 ###常量。請參閱編輯。並注意這個函數返回km而不是英里。 – Parfait

+0

它沒有改變一件事。但無論如何,請不要介意。然而,執行這個查詢「SELECT TOP 100 tblZip.Zipcode,tblZip.City,tblZip.Lat,tblZip.Lon,GetDistance(40.81,-73.04,tblZip.Lat,tblZip。[Lon])AS距離 FROM tblZip Where GetDistance (40.81,-73.04,tblZip.Lat,tblZip。[Lon])<4, ;「導致「數據類型不匹配」錯誤。我不知道爲什麼,但我發現GetDistance()是問題所在。順便說一句,我將存儲過程的最後一行從GetMiles改爲GetDistance。 –

相關問題