2009-04-09 38 views
6

我繼承了一個表的結構是這樣的:選擇最近美國從歷史記錄表

ID Name Timestamp Data 
---------------------------- 
1 A  40   ... 
2 A  30   ... 
3 A  20   ... 
4 B  40   ... 
5 B  20   ... 
6 C  30   ... 
7 C  20   ... 
8 C  10   ... 

ID是一個標識字段,主鍵,也有非唯一索引上NameTimestamp領域。

什麼是最有效的方式來獲取最新的每個項目名稱記錄,即在上述行表,和應當返還,因爲它們是最先進的TO-日期條目分別爲A,BC

回答

13

的SQL Server 2005(以後):

WITH MostRecentRows AS 
(
    SELECT ID, Name, Data, 
    ROW_NUMBER() OVER (PARTITION BY Name ORDER BY TimeStamp DESC) AS 'RowNumber' 
    FROM MySchema.MyTable 
) 
SELECT * FROM MostRecentRows 
WHERE RowNumber = 1 
+0

+1正是我想也是如此。 – Sung 2009-04-09 12:34:06

+0

呵呵。 +1。我得到這個工作,但我不能告訴你是否`MostRecentRows`,`Row_Number()`,或`PARTITION`是否在做魔術。 – jp2code 2012-06-19 20:43:39

+0

正是我在找什麼 – arjun 2015-01-13 08:39:23

5

假設有每名沒有重複的時間戳,這樣的事情應該工作:

SELECT ID, Name, Timestamp, Data 
FROM test AS o 
WHERE o.Timestamp = (SELECT MAX(Timestamp) 
        FROM test as i 
        WHERE i.name = o.name) 
3

的SQL Server 2000:

SELECT 
    ID, Name, Timestamp, Data 
FROM 
    DataTable 
    INNER JOIN 
    (
    SELECT ID, MAX(Timestamp) Timestamp FROM DataTable GROUP BY ID 
) latest ON 
    DataTable.ID = Latest.ID AND 
    DataTable.Timestamp = Latest.Timestamp 
0

如果您使用的是SQL Server 2005/2008,那麼Mitch Weat已經列出的CTE解決方案是最好的性能角度。但是,如果您使用的是SQL Server 2000,那麼您不能認爲沒有重複的Name | TimeStamp組合。使用下面的代碼,每個姓名只返回一個記錄:如果您添加另一條記錄像9個C 30

SELECT ID 
    , Name 
    , TimeStamp 
    , Data 
FROM DataTable dt 
INNER JOIN 
    (SELECT Name 
    , MIN(DataTable.ID) AS MinimumID 
FROM DataTable 
INNER JOIN 
    (SELECT Name 
     , MAX(Timestamp) AS Timestamp 
    FROM DataTable 
    GROUP BY Name) latest 
    ON DataTable.Name = Latest.Name 
    AND DataTable.Timestamp = Latest.Timestamp 
GROUP BY Name) MinimumLatest 
ON dt.ID = MinimumLatest.ID 

這樣,那麼這將只返回ID 6.如果你不走這一步,那麼你可能最終迴歸9個C 30和6個C 30

0

另一個簡單的方法:

SELECT ID,Name,Timestamp, Data 
FROM Test_Most_Recent 
WHERE Timestamp = (SELECT MAX(Timestamp) 
       FROM Test_Most_Recent 
       group by Name);