代码之家  ›  专栏  ›  技术社区  ›  Compile This

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

  •  7
  • Compile This  · 技术社区  · 15 年前

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

    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 是标识字段和主键,并且在 Name Timestamp 领域。

    对于每个项名称(即在上表中的行),获取最新记录的最有效方法是什么? , 应返回,因为它们是项目的最新条目 , C 分别。

    5 回复  |  直到 12 年前
        1
  •  13
  •   Simon P Stevens    12 年前

    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
    
        2
  •  5
  •   Jon    15 年前

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

    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
  •  3
  •   Tomalak    15 年前

    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
    
        4
  •  0
  •   Mariusz Jamro    12 年前

    另一个简单的方法:

    SELECT ID,Name,Timestamp, Data
    FROM   Test_Most_Recent
    WHERE Timestamp = (SELECT MAX(Timestamp)
                     FROM Test_Most_Recent
                     group by Name);
    
        5
  •  0
  •   Mariusz Jamro    12 年前

    如果您使用的是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
    

    因此,如果您添加另一个记录,如9c 30,那么这将只返回id 6。如果你不走这么远,那么你可能会返回9 C 30和6 C 30。