2012-08-13 30 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