Reputation: 279
I'm stumped with this query. I have a deal table with deals for different doctors. There is a many to many between deals and doctors (more than one doctor per deal is possible). I need to find the deals with the closest doctors to a given user's latitude and longitude. I have a stored procedure that takes care of finding the distance.
Select d.dealID, do.doctorID,
dbo.fn_latlongdist($userlat,$userlong,do.doctorLatitude,do.doctorLongitude) as distance
From y_Deals d
JOIN y_deals_doctor dd ON dd.dealID = d.dealID
JOIN Doctor do on dd.doctorID = do.doctorID
ORDER BY distance
Now I want to group by the dealID so I don't return multiple deals. Problem is I want to return the doctorID with the minimum distance. Doesn't seem like there's any aggregate function that would surround doctorID that would return the doctorID with the minimum distance column.
How should I approach this?
Upvotes: 1
Views: 3499
Reputation: 31250
See if this works for you
Select * From
(
Select
d.dealID
, do.doctorID
, dbo.fn_latlongdist($userlat, $userlong, do.doctorLatitude, do.doctorLongitude) as Distance
, ROW_NUMBER() OVER (PARTITION BY d.dealID ORDER BY dbo.fn_latlongdist($userlat, $userlong, do.doctorLatitude, do.doctorLongitude)) AS RowNumber
From
y_Deals d
JOIN
y_deals_doctor dd ON dd.dealID = d.dealID
JOIN
Doctor do on dd.doctorID = do.doctorID
) T
Where
T.RowNumber = 1
UPDATE:
;With AllData As
(
Select
d.dealID
, do.doctorID
, dbo.fn_latlongdist($userlat, $userlong, do.doctorLatitude, do.doctorLongitude) as Distance
, ROW_NUMBER() OVER (PARTITION BY d.dealID ORDER BY dbo.fn_latlongdist($userlat, $userlong, do.doctorLatitude, do.doctorLongitude)) AS RowNumber
From
y_Deals d
JOIN
y_deals_doctor dd ON dd.dealID = d.dealID
JOIN
Doctor do on dd.doctorID = do.doctorID
)
,DrCount As
(
Select
dealID
, Count(Distinct doctorID) as doctorCount
From
AllData
Group By
dealID
)
Select
*
From
AllData A
Inner Join
DrCount C
On
A.dealID = C.dealID
Where
A.RowNumber = 1
Upvotes: 1
Reputation: 6217
Another option is to use the technique discussed in http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/. It doesn't depend on ROW_NUMBER(), which isn't available for a lot of DB engines.
Here's an example where distance is a column in the doctor table instead of a calculated function. Adapt as needed:
SELECT
Doctors.ID, DoctorName, Distance, DealName
FROM
(SELECT DealID, Min(Doc.Distance) as Dist
FROM DoctorDeals, Doctors as Doc
WHERE DoctorDeals.DoctorID = Doc.ID
GROUP BY DealID) as T,
DoctorDeals, Deals, Doctors
WHERE
T.Dist = Doctors.Distance
AND
T.DealID = DoctorDeals.DealID
AND
DoctorDeals.DoctorID = Doctors.ID
AND
DoctorDeals.DealID = Deals.ID
Upvotes: 1