我正在尝试为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
的数据并不总是相同,因此会返回重复数据。
我只需要左边连接表的第一行。
有任何想法/建议吗?
谢谢!
答案 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
交叉申请是这种情况的便利工具。它的工作方式类似于连接,但您可以在子查询中使用变量。