GROUP BY中的ORDER与计算字段

时间:2011-09-21 08:59:12

标签: mysql

我有一个查询,在给定纬度和经度的情况下检索特定半径内的位置实体。

我现在正在尝试调整该查询以返回特定半径范围内的用户列表,其中包含最近的位置。我的问题是,如果我使用用户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错误,因为我的子查询返回了多个字段。

任何想法如何解决这个问题?谢谢!

1 个答案:

答案 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

我不确定语法是否正常,尝试调整一下并希望它能正常工作