如何在MySQL中搜索公里附近的位置

时间:2017-03-21 03:23:44

标签: mysql location

我的数据库如下所示。如何在5公里范围内将location_id列入列表中。数据库表中已有纬度和经度数字。请参阅我的数据库结构图。

- school_id
- location_id
- school_name
- lat
- lng

这是数据库结构图像:

enter image description here

我已经从这个链接中搜索过了 How to find nearest location using latitude and longitude from sql database? 我不明白代码。

  

SELECT id,(3959 * acos(cos(弧度(37))* cos(弧度(纬度))*   cos(弧度(lng) - 弧度(-122))+ sin(弧度(37))* sin(   弧度(纬度))))AS距离标记的距离<1。 25   ORDER BY距离LIMIT 0,20;

3 个答案:

答案 0 :(得分:5)

常数字 3959 表示地球半径的近似值,单位为英里。这就是“大圆距离”表达式以英里为单位返回值的原因。

要获得以千米为单位的距离,只需将 3959 替换为 6371 ,这是地球半径的近似值,单位为km。

参考:https://en.wikipedia.org/wiki/Great-circle_distance

查询正在做的是计算地球上两个点之间的距离(以英里为单位),以纬度和度经度表示。

其中一个点由GCD表达式(37.000000,-122.000000)中的文字值表示。另一个点是数据库中行的(lat,lng)(纬度和度经度)。

查询遍历表中的每一行,并评估GCD表达式以计算距离。 (两点之间沿球体表面的最短线的长度。)

HAVING distance < 25子句排除计算距离大于或等于25或NULL的任何行。

ORDER BY distance子句按距离的上升值,最接近的点首先按顺序返回行。

LIMIT 20子句限制返回前20行。

<强>后续

什么五公里?圣莫尼卡码头水族馆?

那是纬度34.010396,经度-118.496029。

我们可以设置用户定义的变量(以避免在查询文本中传播文字):

 SET @lat =   34.010396 ;
 SET @lng = -118.496029 ;

我们的SQL文本在SELECT列表中包含我们想要从表中返回的列。我们还将包括一个复杂的“Great Circle Distance”表达式,它以千米为单位返回距离。

像这样:

 SELECT m.school_id
      , m.location_id
      , m.school_name
      , m.lat
      , m.lng

      , ( ACOS( COS( RADIANS( @lat  ) ) 
              * COS( RADIANS( m.lat ) )
              * COS( RADIANS( m.lng ) - RADIANS( @lng ) )
              + SIN( RADIANS( @lat  ) )
              * SIN( RADIANS( m.lat ) )
          )
        * 6371
        ) AS distance_in_km

  FROM mytable m
 ORDER BY distance_in_km ASC
 LIMIT 100

表达式中的GCD公式计算两个点之间的距离。

在此查询中,其中一个点是常量 (@lat,@lng),我们之前将其设置为圣莫尼卡码头水族馆的坐标。

另一个点是(m.lat,m.lng),即表格中行的纬度和经度。

因此,在此查询中,distance_in_km表示表格中的行(lat,lng)与圣莫尼卡码头水族馆之间的距离。

由于在访问行时distance_in_km,因此我们无法在WHERE子句中引用该值。

但是我们可以在HAVING子句中引用它。这与WHERE相似,因为它过滤掉了行,但却有很大的不同,因为它在查询执行后期要求很晚。当评估WHERE子句时,它可以引用在访问行时不可用的表达式。

我们可以修改查询以包含HAVING子句。在这种情况下,我们限制在100公里范围内的行,我们将只返回最近的12行......

  FROM mytable m
HAVING distance_in_km <= 100
 ORDER BY distance_in_km ASC
 LIMIT 12

如果我们想要找到除圣莫尼卡码头以外的某个点的距离,我们为该点设置@lat@lng,然后重新执行SQL。

答案 1 :(得分:1)

SELECT *, ((ACOS(SIN(inputLat * PI() / 180) * 
SIN(tableColLat * PI() / 180) + COS(inputLat * PI() / 180) * 
COS(tableColLat * PI() / 180) * COS((inputLng - tableColLng) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) 
as distance FROM gm_shop HAVING distance <= 5 ORDER BY distance ASC;

距离是可以改变的。是KM

答案 2 :(得分:0)

当我解决类似的问题而不是担心地球的曲率和角度。我刚刚使用了毕达哥拉斯的距离。这是一个足够近似的恕我直言。

即。让所有学校距离毕达哥拉斯大约5公里。

select sqrt(pow(lat - curlat,2) + pow(lng - curlng,2)) as distance from markers having distance < XXXXX

您必须计算XXXX的近似值。我学位约111km。如果你没有做任何极端纬度,你不必担心调整它。所以你可以将XXXX设置为0.045