2017-07-03 45 views
0

我有一個跟蹤版本歷史的表。我只想獲取最新版本以及表中每個id的日期。 下面將給我每個id,版本組合的最新日期。我如何只選擇最高記錄?我可以將其存儲在臨時表中,然後使用連接來獲取每個id,版本組合的最高記錄。是否有更好的方法可以在單個步驟中完成此操作?當按兩列分組時,獲取最新記錄SQL Server

的樣本數據

id version  timestamp 
123 1.5   2015-03-28 08:21:04.563 
123 1.0   2015-03-21 12:58:24.730 
234 1.5   2016-10-15 23:08:09.550 
345 1.5   2016-05-10 15:18:09.707 
345 1.5   2016-09-02 21:30:00.657 

預計輸出

id version  timestamp 
123 1.5   2015-03-28 08:21:04.563 
234 1.5   2016-10-15 23:08:09.550 
345 1.5   2016-09-02 21:30:00.657 

查詢

select id,version,max(dt_create) 
from version_history (nolock) 
group by id,version 
order by id 

我都試過,但我得到了同樣的結果如上

select * from 
( 
    select id,version,dt_create,row_number() over (partition by id,version order by dt_create desc) as a 
    from version_history (nolock) 
) b 
where a=1 
order by id 

回答

0

第二個查詢我的作品後,我從分區子句刪除版本

select * from 
( 
    select id,version,dt_create,row_number() over (partition by id order by dt_create desc) as a 
    from version_history (nolock) 
) b 
where a=1 
order by id 
1

您可以使用WITH TIES子句

Declare @YourTable Table ([id] int,[version] varchar(50),[timestamp] datetime) 
Insert Into @YourTable Values 
(123,1.5,'2015-03-28 08:21:04.563') 
,(123,1.0,'2015-03-21 12:58:24.730') 
,(234,1.5,'2016-10-15 23:08:09.550') 
,(345,1.5,'2016-05-10 15:18:09.707') 
,(345,1.5,'2016-09-02 21:30:00.657') 

Select Top 1 with ties * 
From @YourTable 
Order By Row_Number() over (Partition By ID Order By timestamp Desc) 

返回

id version timestamp 
123 1.5  2015-03-28 08:21:04.563 
234 1.5  2016-10-15 23:08:09.550 
345 1.5  2016-09-02 21:30:00.657 
+0

Thanks.My表中有2.1億記錄,這是40分鐘以上。使用加入我得到的結果在8分鐘。 –

+0

@inquisitive_mind高興你有一個決議。無法想象爲什麼你得到了40+分鐘,除非你將數據加載到表變量中。 –

1

我看到你能夠通過分區來實現這一點,但是我想向你展示另一種方法。您可以比較自己的表現並查看最快的表現 - (我假設分區更好)。

首先,我們知道甚至最新版本可能有多個日期,所以你真的不想爲每個ID的最大版本,而是你想要的最大日期!

首先,設置:

DECLARE @table TABLE (ID INT, [Version] DECIMAL(18, 2), [TimeStamp] DATETIME) 

INSERT INTO @table 
VALUES 
(123, 1.5, '2015-03-28 08:21:04.563'), 
(123, 1.5, '2015-03-21 12:58:24.730'), 
(234, 1.5, '2016-10-15 23:08:09.550'), 
(345, 1.5, '2016-05-10 15:18:09.707'), 
(345, 1.5, '2016-09-02 21:30:00.657') 

現在,讓每個ID與最大日期:

SELECT ID, 
     MAX([TimeStamp]) AS MaxTimeStamp 
FROM @table 
GROUP BY ID 

這給了我們什麼,我們想:

ID   MaxTimeStamp 
----------- ----------------------- 
123   2015-03-28 08:21:04.563 
234   2016-10-15 23:08:09.550 
345   2016-09-02 21:30:00.657 

(3 row(s) affected) 

現在我們只需要包含版本。這應該是很容易的,因爲我們可以做ID和日期自聯接:

SELECT T.ID, 
     MAX(T.[TimeStamp]) AS [MaxTimeStamp], 
     T2.[Version] AS [MaxVersion] 
FROM @table T 
JOIN @table T2 
    ON T.ID = T2.ID 
    AND T.[TimeStamp] = T2.[TimeStamp] 
GROUP BY T.ID, T2.[Version] 

這爲我們提供了以下結果:

ID   MaxTimeStamp   MaxVersion 
----------- ----------------------- --------------------------------------- 
123   2015-03-28 08:21:04.563 1.50 
234   2016-10-15 23:08:09.550 1.50 
345   2016-09-02 21:30:00.657 1.50 

(3 row(s) affected) 

注意,我們要加入我們的原始查詢到同樣的表 - 按ID和日期,就像討論過的一樣。但是,我們現在選擇的附加列,版本,所以它需要包含在GROUP BY

或者,您也可以通過使用CROSS APPLY獲得相同的結果:

SELECT T.ID, 
     MAX(T.[TimeStamp]) AS MaxTimeStamp, 
     T2.[Version] 
FROM @table T 
CROSS APPLY 
    (
     SELECT Version 
     FROM @table T2 
     WHERE T2.ID = T.ID 
     AND T2.[TimeStamp] = T.[TimeStamp] 
    ) T2 
GROUP BY T.ID, T2.[Version]