我想从表中获取5行,其中" lat"值最接近30.我正在开发谷歌MAP应用程序,我需要距离数据库最近的5个位置。 我的表看起来像那样,
答案 0 :(得分:5)
MySQL提供了一个Math函数,可以将负数转换为绝对值。通过使用它,您可以得到五个最接近的位置,无论它们的纬度是略低于还是高于30:
ORDER BY ABS(lat - 30) ASC LIMIT 5
ASC
是可选的,因为它是所有DBMS中的默认排序顺序(感谢Gordon)。
答案 1 :(得分:1)
在地图上“最近的位置”应该基于两个点的距离,否则 lat 30.00,long 75.00 将是“最近的”位置。
两点(纬度/经度)之间距离的精确计算基于Haversine formula:
DEGREES(ACOS(COS(RADIANS(ref_latitude)) *
COS(RADIANS(latitude)) *
COS(RADIANS(ref_longitude) - RADIANS(longitude)) +
SIN(RADIANS(ref_latitude)) *
SIN(RADIANS(latitude)))) AS distance
latitude = `lat`
longitude = `long`
ref_latitude & ref_longitude = the point you want to find the nearest locations from
`DOUBLE` should be used for calculation
这会产生度数,乘以 111.195 表示近似距离(公里)或 69.093 (英里数)。
如果您想要附近的位置,可以使用Pythagorean theorem
进行更简单的计算sqrt(power(lat-ref_latitude, 2) +
power((lng-ref_longitude)*cos(radians(ref_latitude)), 2))
再次乘以 111.195 表示公里数或 69.093 表示里程数。
现在只需ORDER BY
这个距离。
而不是与数据库中的所有行进行比较,您应该限制要比较的行数,例如:
WHERE latitude BETWEEN ref_latitude - 0.2 and ref_latitude + 0.2
AND longitude BETWEEN ref_longitude - 0.2 and ref_longitude + 0.2
顺便说一下,一些DBMS支持地理空间扩展,如distance
函数或地理空间索引。
答案 2 :(得分:0)
请注意,如果您希望有效地执行此操作,并且在lat
上有索引,那么以下更复杂的查询应该会更好:
select t.*
from ((select t.*
from table t
where lat <= 30
order by lat desc
limit 5
) union all
(select t.*
from table t
where lat > 30
order by lat asc
limit 5
)
) t
order by abs(lat - 30)
limit 5;
这两个子查询可以使用lat
上的索引来避免排序。外部查询只排序10行。