2012-08-13 31 views
1

我试图获得SELECT语句的每一行的第一个结果LEFT JOIN仅从左加入获取第一个结果

因为现在,如果我在连接表中有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

你能解释一下你如何定义 “'FIRST'”? – 2012-08-13 17:21:33

+0

我需要从'LEFT JOIN'中取得的第一个结果。但告诉你,我想我会需要一个子查询,因为没有加入顺序... – TomShreds 2012-08-13 17:23:45

+0

是的,我仍然不知道你的意思是“第一结果” – 2012-08-13 17:24:11

回答

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 

交叉应用是这种情况的一个方便的工具。它像联接一样工作,但可以在子查询中使用变量。

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; 
+0

这工作真棒。我遇到的唯一问题是我必须将该查询放在另一个查询的JOIN语句中,现在似乎无法使用WITH进行此操作。但是,这仍然有效,我会努力使其适应。谢谢! – TomShreds 2012-08-13 17:36:12

+0

你可以在CTE之后加入'x'。 – 2012-08-13 17:36:53