Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 从历史记录表中选择最近的状态_Sql_Tsql - Fatal编程技术网

Sql 从历史记录表中选择最近的状态

Sql 从历史记录表中选择最近的状态,sql,tsql,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

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

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
是一个标识字段和主键,在
名称
时间戳
字段上有非唯一索引

获取每个项目名称的最新记录的最有效方法是什么,即在上表中,分别返回146,因为它们是项目ABC的最新条目。

SQL Server 2005(以后):


假设每个名称没有重复的时间戳,类似这样的方法应该可以工作:

SELECT ID, Name, Timestamp, Data
FROM test AS o
WHERE o.Timestamp = (SELECT MAX(Timestamp)
                     FROM test as i
                     WHERE i.name = o.name)
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

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

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
因此,如果您添加另一条记录,比如9C30,那么它将只返回ID6。如果您没有走这么远,那么您可能会返回9 C30和6 C30。

另一种简单的方法:

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

是的,只有当没有重复的时间戳时,这才有效。CTE描述绝对更安全,因为它只返回一行。如果一个时间戳有多条记录,则可能返回多条记录。我完全了解这一事实。如果可能存在重复的时间戳,则额外的外部GROUP BY子句会转移此风险。嗯+1.我成功了,但我不能告诉你是
MostRecentRows
Row\u Number()
,还是
PARTITION
正在发挥作用。这正是我所期待的卓越方法。这对我很有用。谢谢
SELECT ID,Name,Timestamp, Data
FROM   Test_Most_Recent
WHERE Timestamp = (SELECT MAX(Timestamp)
                 FROM Test_Most_Recent
                 group by Name);