选择表中每一行的最新版本

发布于 2024-08-04 19:56:39 字数 452 浏览 3 评论 0原文

我的表结构包含 id 和 id 的复合主键;修订版,其中两者都是整数。

我需要一个查询来返回每行的最新版本。如果我理解这个如果回答正确,那么以下内容将在 Oracle DB 上运行。

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

我正在使用 SQL Server (2005),并且需要一个高性能查询来执行相同的操作。

I have table structures that include a composite primary key of id & revision where both are integers.

I need a query that will return the latest revision of each row. If I understood this answer correctly then the following would have worked on an Oracle DB.

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

I am using SQL Server (2005) and need a performant query to do the same.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ゃ人海孤独症 2024-08-11 19:56:39

我认为这应该有效(我没有测试)......

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

I think this should work (I didn't test it)...

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
我是有多爱你 2024-08-11 19:56:39

请参阅这篇文章 ayende 评估最佳策略。

See this post by ayende for an ealuation of the Best strategies.

荆棘i 2024-08-11 19:56:39

我会尝试创建一个像这样的子查询:

SELECT Id, Title 
FROM Task T, (Select ID, Max(Revision) MaxRev  from Task group by ID) LatestT
WHERE T.Revision = LatestT.MaxRev and T.ID = LatestT.ID

另一种选择是“作弊”并创建一个触发器,如果​​添加一个项目,该触发器会将修订标记为最新修订。
然后将该字段添加到索引中。 (我会将表链接到仅插入)

此外,ID 上的索引、Revision desc 也可以帮助提高性能。

I would try to create a subquery like this:

SELECT Id, Title 
FROM Task T, (Select ID, Max(Revision) MaxRev  from Task group by ID) LatestT
WHERE T.Revision = LatestT.MaxRev and T.ID = LatestT.ID

Another option is to "cheat" and create a trigger that will flag the revision as latest revision if one item is added.
Then add that field to the index. (I would link the table to insert only)

Also an index on ID, Revision desc could help the performance.

余生再见 2024-08-11 19:56:39

您发布的查询将在 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

The query you posted will work in SQL 2005 (in compatibility mode 90) with the syntax errors corrected:

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
苏璃陌 2024-08-11 19:56:39

试试这个:

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)

try this:

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

OUTPUT:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文