通过纬度和经度(地理定位)查找子公司

3
我正在寻找一个快速的MySQL查询,可以从一个简单的表中返回最近的位置:
表格:locations:
id |    city    |   latitude   |  longitude
-----------------------------------------------
1  |   Berlin   |   52.524268  |   13.406290
-----------------------------------------------
2  |   London   |   51.508129  |  -0.1280050    
-----------------------------------------------
3  |   Hamburg  |   53.551084  |   9.9936817
-----------------------------------------------

客户端坐标( + ):
$intLat = '52.370215700000000000'; // lat Amsterdam
$intLon = '4.895167899999933000';  // lon Amsterdam

大多数提供的示例 @SO 都基于距离计算。
即使使用来自 Birmingham 的坐标,它仍然返回 id=1 (柏林)。查询应该返回伦敦,因为它比柏林更近。不应该吗?
SELECT *, ( 3959 * acos( cos( radians($intLat) ) 
                  * cos( radians( latitude ) ) 
                  * cos( radians( longitude ) 
                  - radians($intLon) ) + sin(radians($intLat) ) 
                  * sin( radians( latitude ) ) ) ) AS distance 
FROM locations 
HAVING distance < 10 
   AND id IN(1,2,3) 
LIMIT 1;

2
你需要使用ORDER BY计算出的距离ASC,这样LIMIT才能选择最低的距离结果。 - Mark Baker
@MarkBaker 哎呀,我太蠢了...谢谢! - mate64
愚蠢是我们学习的方式:我们因此感到尴尬,所以再也不会犯同样的错误了 :) - Mark Baker
顺便说一句:如果distance没有在其他地方使用且不需要distance < 10,那么可以省略*3959acos()步骤。另外,反转、排序,然后再处理。 - chux - Reinstate Monica
1个回答

2
问题在于你正在选择所有半径为10的位置。
然后从该结果集中随机选择1个结果,使用LIMIT 1
你需要按距离排序,以便最近的位置在顶部。
像这样:
SELECT *, ( 3959 * acos( cos( radians($intLat) ) 
            * cos( radians( latitude ) ) 
            * cos( radians( longitude ) 
            - radians($intLon) ) + sin(radians($intLat) ) 
            * sin( radians( latitude ) ) ) ) AS distance 

FROM locations 
HAVING distance < 10 
   AND id IN(1,2,3)
ORDER BY distance ASC  <<-- add this line
LIMIT 1;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接