SQL:根据另一列聚合一列

时间:2011-03-25 17:04:29

标签: sql sql-server

我对此查询感到困惑。我有一个交易表,为不同的医生交易。交易和医生之间有很多对(每笔交易可能超过一名医生)。我需要找到最近医生与特定用户的纬度和经度的交易。我有一个存储过程,负责找到距离。

    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

现在我想通过dealID分组,所以我不会返回多个交易。问题是我想以最小距离返回doctorID。似乎没有任何聚合函数围绕doctorID,它将以最小距离列返回doctorID。

我该如何处理?

2 个答案:

答案 0 :(得分:1)

看看这是否适合你

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

更新:

;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

答案 1 :(得分:1)

另一种选择是使用http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/中讨论的技术。它不依赖于ROW_NUMBER(),它不适用于许多数据库引擎。

这是一个例子,其中距离是医生表中的一列而不是计算的函数。根据需要进行调整:

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