The basic structure of my query is this:
- I have a
profiles
table with profile information - I have a
locations
table with location coordinates - I have a
location_assignment
table which just contains (profile_id, location_id) pairs
Each profile is assigned to one or more locations, and what I'm trying to do is search the profiles, and return them in order of distance to the location coordinates. My query to do so is (with only the relevant parts included) as follows:
SELECT *,
(3959*acos(cos(radians(30.292424))*cos(radians(lat))*cos(radians(lng)-
radians(-97.73856))+sin(radians(30.292424))*sin(radians(lat)))) AS distance,
`profiles`.`name` as profilename,
`profiles`.`profile_id` as profile_id
FROM (`profiles`)
JOIN `location_assignment`
ON `profiles`.`profile_id` =`location_assignment`.`profile_id`
JOIN `locations`
ON `location_assignment`.`location_id` = `locations`.`location_id`
HAVING `distance` < 50
ORDER BY `distance`
LIMIT 3"
(That grosstastic thing in the select line converts the lat/lng fields in the locations
table into a distance from a given input lat/lng)
However, my query makes profiles appear multiple times in the results, once for each location he is assigned to. I would like each profile to appear only once, with the information for the location with the shortest distance.
My knee-jerk reaction is to use group_by location_id
, but I want to make sure I get the location with the minimum distance to the input coordinates.
HAVING
in your code, so either you are missing aGROUP BY
or you want aWHERE
instead. – Rafa PaezWHERE
. The full clause is "WHEREprocedures
.procedure_id
= 18 ANDbase_price
> 0 HAVINGdistance
< 50 ORDER BYdistance
" – Mala