Выберите последнюю версию каждой строки в таблице - PullRequest
1 голос
/ 16 сентября 2009

У меня есть структуры таблиц, которые включают составной первичный ключ id & revision, где оба являются целыми числами.

Мне нужен запрос, который будет возвращать последнюю версию каждой строки. Если бы я правильно понял этот ответ , то в БД Oracle сработало бы следующее:

SELECT Id, Title
FROM ( SELECT Id, Revision, MAX(Revision) OVER (PARTITION BY Id) LatestRevision FROM Task )
WHERE Revision = LatestRevision

Я использую SQL Server (2005) и мне нужен запрос на выполнение, чтобы сделать то же самое.

Ответы [ 5 ]

2 голосов
/ 16 сентября 2009

Я думаю, что это должно работать (я не проверял) ...

SELECT      ID, 
            Title
FROM        Task AS T
INNER JOIN
(
    SELECT          ID, 
                    Max(Revision)
    FROM            Task
    GROUP BY        ID
) AS sub
ON          T.ID = sub.ID
AND         T.Revision = sub.Revision
2 голосов
/ 16 сентября 2009

См. этот пост от ayende для оценки лучших стратегий.

1 голос
/ 16 сентября 2009

Я бы попытался создать подзапрос, подобный этому:

SELECT Id, Заголовок ОТ задачи T, (Выберите идентификатор, Макс. (Версия) MaxRev из группы задач по идентификатору) ГДЕ T.Revision = LatestT.MaxRev и T.ID = LatestT.ID

Другой вариант - «обмануть» и создать триггер, который помечает ревизию как последнюю ревизию, если добавлен один элемент. Затем добавьте это поле в индекс. (Я бы связал таблицу только для вставки)

Также индекс на ID, Revision desc может помочь производительности

0 голосов
/ 16 сентября 2009

попробуйте это:

DECLARE @YourTable table(RowID int, Revision int, Title varchar(10))
INSERT INTO @YourTable VALUES (1,1,'A')
INSERT INTO @YourTable VALUES (2,1,'B')
INSERT INTO @YourTable VALUES (2,2,'BB')
INSERT INTO @YourTable VALUES (3,1,'C')
INSERT INTO @YourTable VALUES (4,1,'D')
INSERT INTO @YourTable VALUES (1,2,'AA')
INSERT INTO @YourTable VALUES (2,3,'BBB')
INSERT INTO @YourTable VALUES (5,1,'E')
INSERT INTO @YourTable VALUES (5,2,'EE')
INSERT INTO @YourTable VALUES (4,2,'DD')
INSERT INTO @YourTable VALUES (4,3,'DDD')
INSERT INTO @YourTable VALUES (6,1,'F')

;WITH YourTableRank AS
(
SELECT
    RowID,Revision,Title, ROW_NUMBER() OVER(PARTITION BY RowID ORDER BY RowID,Revision DESC) AS Rank
    FROM @YourTable
)
SELECT
    RowID, Revision, Title
    FROM YourTableRank
    WHERE Rank=1

ВЫВОД:

RowID       Revision    Title
----------- ----------- ----------
1           2           AA
2           3           BBB
3           1           C
4           3           DDD
5           2           EE
6           1           F

(6 row(s) affected)
0 голосов
/ 16 сентября 2009

Отправленный вами запрос будет работать в SQL 2005 (в режиме совместимости 90) с исправленными синтаксическими ошибками:

SELECT t1.Id, t1.Title
FROM ( SELECT Id, Revision, MAX(Revision) OVER (PARTITION BY Id) LatestRevision FROM Task ) AS x
JOIN Task as t1
ON   t1.Revision = x.LatestRevision
AND  t1.id       = x.id
...