仅获得LEFT JOIN的第一个结果

时间:2012-08-13 17:16:07

标签: sql sql-server sql-server-2008 group-by left-join

我正在尝试为LEFT JOIN语句的每一行获取SELECT的第一个结果。

因为现在,如果我在连接表中有100行,我将从SELECT获得相同行的100倍。我只需要第一个连接的行,这样我就不会得到任何副本。

我无法使用GROUP BY,因为我必须从表中获得多于一行。

以下是我的查询的基本版本:

SELECT bg.PatientID, DATEDIFF(hour, bg.CreateDate, GETDATE()) TimeToTarget 
FROM BloodGlucose bg
    LEFT JOIN IVProtocol i ON i.PatientID = bg.PatientID
WHERE bg.BGValue >= i.TargetLow AND bg.BGValue <= i.TargetHigh
ORDER BY bg.PatientID ASC

我尝试使用DISTINCT,但由于来自bg.CreateDate的数据并不总是相同,因此会返回重复数据。

我只需要左边连接表的第一行。

有任何想法/建议吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

;WITH x AS 
(
  SELECT 
    bg.PatientID, 
    TimeToTarget = DATEDIFF(hour, bg.CreateDate, GETDATE()),
    rn = ROW_NUMBER() OVER (PARTITION BY bg.PatientID ORDER BY bg.CreatedDate DESC) 
  FROM dbo.BloodGlucose AS bg
  LEFT JOIN dbo.IVProtocol AS i 
  ON i.PatientID = bg.PatientID
  WHERE bg.BGValue >= i.TargetLow 
  AND bg.BGValue <= i.TargetHigh
)
SELECT PatientID, TimeToTarget
FROM x
WHERE rn = 1
ORDER BY PatientID;

加入其他结果:

;WITH x AS 
(
  ... same as above ...
)
SELECT x.PatientID, x.TimeToTarget, y.Something
 FROM x INNER JOIN dbo.SomethingElse AS y
 ON x.PatientID = y.PatientID
 WHERE x.rn = 1
 ORDER BY x.PatientID;

答案 1 :(得分:2)

SELECT bg.PatientID, DATEDIFF(hour, bg.CreateDate, GETDATE()) TimeToTarget 
FROM BloodGlucose bg
cross apply (
 select top 1 *
 from IVProtocol i
 where i.PatientID = bg.PatientID
 order by SOME_CRITERA
) i
WHERE bg.BGValue >= i.TargetLow AND bg.BGValue <= i.TargetHigh
ORDER BY bg.PatientID ASC

交叉申请是这种情况的便利工具。它的工作方式类似于连接,但您可以在子查询中使用变量。