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
精彩评论