我有一个查询,在给定纬度和经度的情况下检索特定半径内的位置实体。
我现在正在尝试调整该查询以返回特定半径范围内的用户列表,其中包含最近的位置。我的问题是,如果我使用用户ID进行GROUP BY,那么我就无法对这些位置进行排序,只返回最新的位置。
我试过跟随ypercube's advice使用了一个让我走到这一步的子查询:
SET @mylon = -1.095414;
SET @mylat = 50.79486;
SELECT u.*, dest.*
FROM users AS u
JOIN locations AS dest
ON dest.id =
(
SELECT l.id, 3956 * 2 * ASIN(SQRT(POWER(SIN((@mylat - abs(l.latitude)) * pi()/180/2),
2) + COS(@mylat * pi()/180) * COS(abs(l.latitude) *
pi()/180) * POWER(SIN((@mylon - l.longitude) *
pi()/180/2),2))) as distance
FROM locations AS l
HAVING distance < 0.5
ORDER BY
l.created DESC
LIMIT 1
)
但是,这会返回一个SQL错误,因为我的子查询返回了多个字段。
任何想法如何解决这个问题?谢谢!
答案 0 :(得分:1)
首先,您的子查询必须只返回一个应该与dest.id匹配的id。 我没有看到你使用GROUP BY所以你应该用WHERE替换HAVING。 我想你可以直接说WHERE(3956 * 2 * ASIN(.......)&lt; 0.5这样你就不会把这个计算放在结果中而只留下id
SET @mylon = -1.095414;
SET @mylat = 50.79486;
SELECT u.*, dest.*
FROM users AS u
JOIN locations AS dest
ON dest.id =
(
SELECT l.id
FROM locations AS l
WHERE (3956 * 2 * ASIN(SQRT(POWER(SIN((@mylat - abs(l.latitude)) * pi()/180/2),
2) + COS(@mylat * pi()/180) * COS(abs(l.latitude) *
pi()/180) * POWER(SIN((@mylon - l.longitude) *
pi()/180/2),2)))) < 0.5
ORDER BY
l.created DESC
LIMIT 1
)
要返回计算,您也可以创建一个像这样的临时表
SET @mylon = -1.095414;
SET @mylat = 50.79486;
SELECT u.*, dest.*
FROM users AS u
JOIN (
SELECT l.id, l.created, (3956 * 2 * ASIN(SQRT(POWER(SIN((@mylat - abs(l.latitude)) * pi()/180/2),
2) + COS(@mylat * pi()/180) * COS(abs(l.latitude) *
pi()/180) * POWER(SIN((@mylon - l.longitude) *
pi()/180/2),2)))) as distance
FROM locations ) as location_table_tmp
ON u.id = location_table_tmp.id
ORDER BY location_table_tmp.created DESC
我不确定语法是否正常,尝试调整一下并希望它能正常工作