2011-11-17 124 views
2

我有三個表:SQL加入以獲得最新記錄

  • Measurements (MeasureID, Time, Distance, Value)
  • Events(EventID, Time Value)
  • EventValues (EventDataID, EventID, Type, Value)

我需要爲每一個測量,最近的事件(在過去)及其關聯的事件值數據。

我當前的查詢是相當難看:

SELECT 
    M.*, 
    (SELECT TOP 1 EV.value FROM [Event] E JOIN EventValues EV ON E.EventID = EV.EventID 
    WHERE M.Time >= E.Time ORDER BY M.Time-E.Time) AS Data, 
FROM [Measure] M 
ORDER BY M.Distance 

,並只允許我從EventValues表中選擇一列(我需要更多)

有什麼辦法這個可以用做加入?

編輯:我還需要從測量表中選擇所有條目,即使他們之前的第一個事件(即只選擇了加入空數據)

+0

如何測量和事件的表realted?沒有外鍵,它們是通過時間值關聯的嗎? – Zohaib

+0

是隻有時間 – Simon

+1

如果對於給定的最近事件有2個EventValue記錄,那麼在這種情況下您的期望是什麼?要查看這兩個記錄還是僅查看其中的一個?此外,臨時表是否可以接受? – mjwills

回答

1

可以使用CROSS APPLY。

SELECT 
    M.*, Data.* 
FROM [Measure] M 
CROSS APPLY 
    (SELECT TOP 1 EV.* FROM [Event] E JOIN EventValues EV ON E.EventID = EV.EventID 
    WHERE M.Time >= E.Time ORDER BY E.Time DESC) AS Data 
ORDER BY M.Distance 
+0

+1這個查詢(幾乎)有效,謝謝 - 但是有一種方法可以包含第一個事件之前的度量表中的條目 – Simon

+0

您可以使用OUTER APPLY而不是CROSS APPLY,您將得到NULLS作爲「數據「(EventValues)列。 – GilM

+0

Im接受了amit-g的這個答案,因爲這在我的情況下表現更好,儘管兩者都產生了正確的結果。 – Simon

1

嘗試這樣的事情(未測試)

SELECT * FROM 
(
    SELECT M.*, E.*, EV.EventDataID, EV.Type, EV.Value, 
     Rank() over (Partition BY M.MeasureID order by M.Time - E.Time) as Rank 
    FROM [Measure] M 
    INNER JOIN [Event] E ON M.Time >= E.Time 
    INNER JOIN EventValues EV ON E.EventID = EV.EventID 
) T 
WHERE Rank = 1 

編輯

SELECT * FROM 
(
    SELECT M.*, E.*, EV.EventDataID, EV.Type, EV.Value, 
     Rank() over (Partition BY M.MeasureID order by M.Time - E.Time) as Rank 
    FROM [Measure] M 
    LEFT JOIN [Event] E ON M.Time >= E.Time 
    LEFT JOIN EventValues EV ON E.EventID = EV.EventID 
) T 
WHERE Rank = 1 
+0

+1這個查詢(幾乎)有效,謝謝 - 但是有沒有辦法在第一個事件之前包含來自測量表的條目? – Simon