从历史记录表中选择最新状态

时间:2009-04-09 10:37:02

标签: sql tsql

我继承了一个结构如下的表:

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字段中有非唯一索引。

获取每个项目名称的最新记录的最有效方法是什么,即上表 1 4 6 应该返回,因为它们分别是项目 A B C 的最新条目。

5 个答案:

答案 0 :(得分:15)

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

答案 1 :(得分: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)

答案 2 :(得分: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

答案 3 :(得分:0)

如果您使用的是SQL Server 2005/2008,那么从性能角度来看,Mitch Weat已经列出的CTE解决方案是最好的。但是,如果您使用的是SQL Server 2000,那么您不能假设没有重复的Name | TimeStamp组合。使用以下代码每个名称只返回一条记录:

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

因此,如果您添加另一条记录,例如9 C 30,那么这只会返回ID 6.如果您没有这么做,那么您最终可能会返回9 C 30和6 C 30.

答案 4 :(得分:0)

另一种简单方法:

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