2017-04-11 46 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。 –

相关问题