Sql 如何有效地过滤出表中表示同一逻辑对象的多个版本的旧版本?

Sql 如何有效地过滤出表中表示同一逻辑对象的多个版本的旧版本?,sql,sql-server,Sql,Sql Server,在SQL Server中,我有一个表,其中包含表示资源的行。当资源发生更改时,它会在同一个表中获得另一行,该行具有相同的ID字段。不幸的是,ID已命名,实际上并不表示唯一的密钥 因此,同一逻辑资源可能有多个列,表示其随时间的变化。每行有一个记录的列。具有最新记录值的行将是该资源的当前版本 因此,如果资源A是创建的,然后更改了三次,那么表中将有四行。如果按记录的ASC排序,则具有该资源的历史记录,最后一行是其当前状态 我想要一个表示每个资源的最新版本的视图。这项工作: SELECT * FROM

在SQL Server中,我有一个表,其中包含表示资源的行。当资源发生更改时,它会在同一个表中获得另一行,该行具有相同的ID字段。不幸的是,ID已命名,实际上并不表示唯一的密钥

因此,同一逻辑资源可能有多个列,表示其随时间的变化。每行有一个记录的列。具有最新记录值的行将是该资源的当前版本

因此,如果资源A是创建的,然后更改了三次,那么表中将有四行。如果按记录的ASC排序,则具有该资源的历史记录,最后一行是其当前状态

我想要一个表示每个资源的最新版本的视图。这项工作:

SELECT * FROM Resources r1
WHERE ID =
  (SELECT TOP 1 ID FROM Resources r2 WHERE r1.ID = r2.ID ORDER BY Logged DESC)
因此,当按Logged DESC排序时,子选择获取ID TOP 1的最新行,然后确保这是外部选择中该行中的唯一表示


我觉得这很慢。我忍不住想,有一种更好的方法来处理一些涉及连接的事情,但我就是不这么想。

你可以使用窗口函数

WITH T AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY id ORDER BY Logged DESC) AS RN
FROM Resources
)
SELECT *
FROM T
WHERE RN =1
或者另一种方式可能是

WITH T AS
(SELECT MAX(Logged) AS Logged,
        ID
FROM Resources
GROUP BY ID
)
SELECT R.*
FROM Resources R
JOIN T ON T.ID=R.ID AND T.Logged = R.Logged

您可以试试这个,但不确定它是否更快:

选择r1。* 来自资源r1 内连接 选择MaxLoggedMax,ID 来自资源 按ID分组 r2 在r1.ID=r2.ID上 和r1.Logged=r2.LoggedMAX 按r1订购。记录描述

17秒,而不是0秒。是的,我想说这很好。