Выбрать самые последние состояния из таблицы истории - PullRequest
9 голосов
/ 09 апреля 2009

Я унаследовал таблицу со структурой примерно так:

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 имеются неуникальные индексы.

Какой самый эффективный способ получить самую последнюю запись для каждого имени элемента, то есть в таблице над строками 1 , 4 и 6 следует должны быть возвращены, поскольку они являются самыми последними записями для элементов A , B и C соответственно.

Ответы [ 5 ]

15 голосов
/ 09 апреля 2009

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
5 голосов
/ 09 апреля 2009

Если в имени нет повторяющихся временных меток, должно сработать что-то вроде этого:

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 голосов
/ 09 апреля 2009

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
0 голосов
/ 12 июля 2012

Еще один простой способ:

SELECT ID,Name,Timestamp, Data
FROM   Test_Most_Recent
WHERE Timestamp = (SELECT MAX(Timestamp)
                 FROM Test_Most_Recent
                 group by Name);
0 голосов
/ 10 апреля 2009

Если вы используете SQL Server 2005/2008, то решение CTE, уже перечисленное Mitch Weat, является лучшим с точки зрения производительности. Однако, если вы используете SQL Server 2000, вы не можете предполагать, что нет повторяющихся имен | 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...