Search code examples
sqlsql-serverstored-proceduresgreatest-n-per-group

Get the latest date for each record


I have a History table (like a log) that records changes to parts:

TransactionID    Part ID          Description        Last Updated
1                1                Fixed O-ring       2006-03-14 20:00:04.700
2                2                Replaced coil      2009-01-02 20:00:04.700
3                1                Replaced coil      2009-01-02 20:00:04.700
4                1                Replaced LED       2002-08-20 20:00:04.700      
5                2                Sealed leakage     2007-03-08 20:00:04.700   
6                3                Replace connector  2004-05-16 20:00:04.700

I have another table that will show what each Part ID stands for, but that is not the problem I'm facing now. I'm required to write a query that returns the latest maintenance done on every parts. So in this case, my expected output would be:

TransactionID    Part ID          Description        Last Updated
2                2                Replaced coil      2009-01-02 20:00:04.700    
3                1                Replaced coil      2009-01-02 20:00:04.700 
6                3                Replace connector  2004-05-16 20:00:04.700

Explanation: For example, the latest maintenance for Part ID #1 was completed on 2009-01-02 20:00:04.700 and so on.

I have tried SELECT DISTINCT but it won't work because basically every rows will be different. I'm completely out of clue. And if I use MAX(Last Updated), it will only return one row of the entire table.

Edited: In any case, I am NOT allowed to use Dynamic query.


Solution

  • SELECT TransactionID
          ,PartID
          ,[Description]
          ,[Last Updated]
    FROM (
        SELECT TransactionID
              ,PartID
              ,[Description]
              ,[Last Updated]
              ,ROW_NUMBER() OVER (PARTITION BY [PartID] ORDER BY [Last Updated] DESC) RN 
        FROM TableName
        )A
    WHERE A.RN = 1
    

    Or you can use CTE

    ;WITH CTE AS
      (
        SELECT TransactionID
              ,PartID
              ,[Description]
              ,[Last Updated]
              ,ROW_NUMBER() OVER (PARTITION BY [PartID] ORDER BY [Last Updated] DESC) RN 
        FROM TableName
      )
    SELECT TransactionID
          ,PartID
          ,[Description]
          ,[Last Updated]  
    FROM CTE 
    WHERE A.RN = 1