mysql - 如何获得子查询最近的距离?
问题描述
我有一个查询来获取基于数据库表中存储的纬度和经度计算后的距离。
每个用户都有自己的纬度和经度,我试图获取离用户位置最近的中心名称。但是当有 2 个位置非常靠近用户时,我的查询会出错,我怎样才能获得可以在子查询中返回的最近的中心名称?
以下是我的 PHP 查询:
SELECT
t1.id, t2.name AS na_name, t3.name AS centre_name, t1.login, t1.login_lat, t1.login_long,
(SELECT centre_name
from centre_location where
(3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.login_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.login_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.login_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18
) AS LOGIN_LOCATION, t1.login_location_accuracy,
t1.logout, t1.logout_lat, t1.logout_long, (SELECT centre_name
from centre_location where
(3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.logout_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.logout_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.logout_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18
) AS LOGOUT_LOCATION, t1.logout_location_accuracy, t1.attendance_device_type , t1.remark
FROM attendance t1
left join user t2 on t1.user_id = t2.id
left join centre t3 on t1.centre_id = t3.id
where t1.id = 10130
我确实尝试了 ORDER BY 和 LIMIT 1,但结果仍然不正确。请参考以下:
SELECT
t1.id, t2.name AS na_name, t3.name AS centre_name, t1.login, t1.login_lat, t1.login_long,
(SELECT centre_name
from centre_location where
(3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.login_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.login_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.login_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18
ORDER BY (3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.login_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.login_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.login_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18 DESC LIMIT 1
) AS LOGIN_LOCATION, t1.login_location_accuracy,
t1.logout, t1.logout_lat, t1.logout_long, (SELECT centre_name
from centre_location where
(3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.logout_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.logout_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.logout_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18
ORDER BY (3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.logout_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.logout_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.logout_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18 DESC LIMIT 1
) AS LOGOUT_LOCATION, t1.logout_location_accuracy, t1.attendance_device_type , t1.remark
FROM attendance t1
left join user t2 on t1.user_id = t2.id
left join centre t3 on t1.centre_id = t3.id
where t1.id = 10130
center_name 应该只返回 1 个值,以便我可以显示/导出到我想要的结果,但有时 center_name 返回超过 1 行,我怎样才能得到最接近的返回值?
解决方案
您的 ORDER BY 子句如下:
ORDER BY (3956 * 2 * ASIN(SQRT( POWER(SIN(( t1.login_lat - centre_lat) * pi()/180 / 2), 2) +COS( t1.login_lat * pi()/180) * COS(centre_lat * pi()/180) * POWER(SIN(( t1.login_long - centre_long) * pi()/180 / 2), 2) ))) <= 0.18 DESC LIMIT 1
简而言之:
ORDER BY (<distance calculation>) <= 0.18 DESC LIMIT 1
虽然它应该是
ORDER BY (<distance calculation>) LIMIT 1
你应该删除<= 0.18
. 您可能还想要ASC
(最短距离优先)而不是DESC
(最长距离优先)。
推荐阅读
- laravel-livewire - Uncaught SyntaxError: Unexpected token < in JSON at position 0 ... in livewire
- python - 打印 scipy 稀疏矩阵而不跳行
- api - 是否有标准的 API 流程图代码应该坚持?
- python - 书签功能 django/python
- sql - 在 SQL (date_trunc) 中,周数最多为数月
- javascript - Reactjs,当可滚动的div扩展时如何使滚动保持在当前位置
- pandas - Pandas,groupby 包括每行分组的行数
- python - 需要帮助在 Python 中编写 Map reduce 以计算每个国家/地区每年每个 item_type 的 avg (unit_price)
- java - 如何将elasticsearch SQL API请求的结果映射到java POJO?
- javascript - chrome tabCapture 内容脚本中的 undefiend