开发者

ORDER within GROUP BY with calculated fields

开发者 https://www.devze.com 2023-04-06 21:22 出处:网络
I have a query that retrieves location entities within a certain radius given a latitude and longitude开发者_StackOverflow社区.

I have a query that retrieves location entities within a certain radius given a latitude and longitude开发者_StackOverflow社区.

I'm now trying to adapt that query to return a list of users within a certain radius, with their most recent location alongside it. My problem is that if I GROUP BY the user id, I can't then sort the locations to only return the most recent one.

I've tried following ypercube's advice on using a subquery which has got me this far:

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
        )

However, this returns an SQL error as I've got more than one field being returned by my subquery.

Any ideas how to fix this? Thanks!


First, your subquery must return only an id that should be matched with the dest.id. I don't see you using GROUP BY so you should replace HAVING with WHERE. I think you can directly say WHERE (3956 * 2 * ASIN(.......) < 0.5 so that you don't put that computation in the result and leave only the 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
    )

To return also the computation you may be able to create a temporary table like this

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

I'm not sure if the syntax is Ok, try to tweak a little bit and hope it works

0

精彩评论

暂无评论...
验证码 换一张
取 消