Based on the following table
基于下表
Table_A
ID Rev Description
-----------------------------------
1 1 Some text.
1 2 Some text. Adding more.
1 3 Some text. Ading more & more.
The above will keep adding a new row when user updates the description.
当用户更新描述时,上面将继续添加新行。
I want to take the row with MAX(Rev) [i.e. the latest description].
我想用MAX(Rev)取行[即最新描述]。
To get this I do the following:
为此,我执行以下操作:
;with AllDescriptions As
(
select
ID
, Rev
, Description
, ROW_NUMBER() over (partition by ID order by Rev desc) as RowNum
from Table_A
Where ID = 1
)
select ID, Rev, Description from AllDescription
where RowNum = 1
Recently I saw a different approach to getting the same result
最近我看到了一种不同的方法来获得相同的结果
select b.* from
(
select ID, MAX(Rev) as MaxRev
from Table_A
where ID = 1
group by ID
) as a
inner join
(
select ID, Rev, Description from Table_A where ID = 1
) as b
on a.ID = b.ID and a.MaxRev = b.Rev
From learning perspective, I want to know Which of the above two approaches is better? Or if there is even better way to do the same?
从学习的角度来看,我想知道上述哪两种方法更好?或者,如果有更好的方法来做同样的事情?
3 个解决方案
#1
1
The second approach looks like a SQL Server 2000 approach before Row_Number()
was introduced. This is the Greatest-n-per-group problem.
在引入Row_Number()之前,第二种方法看起来像SQL Server 2000方法。这是每组最大的问题。
To evaluate them you should look at the execution plans and the I/O Stats by running SET STATISTICS IO ON
要评估它们,您应该通过运行SET STATISTICS IO ON来查看执行计划和I / O统计信息
Of course for the specific example you have given the following would work equally well
当然,对于您给出以下内容的具体示例,同样可以正常工作
select TOP 1
ID
, Rev
, Description
from Table_A
Where ID = 1
ORDER BY Rev desc
#2
1
If you have a parent table with each ID listed only once, this can sometimes outperform other strategies including the row_number solution:
如果您有一个父表,每个ID只列出一次,这有时可以胜过其他策略,包括row_number解决方案:
SELECT
X.*
FROM
ParentTable P
CROSS APPLY (
SELECT TOP 1 *
FROM Table_A A
WHERE P.ID = A.ID
ORDER BY A.Rev DESC
) X
And the crazy, patented (just kidding), single scan magic query which can often outperform other methods as well:
而疯狂的,专利的(只是开玩笑),单扫描魔术查询,通常也可以胜过其他方法:
SELECT
ID,
Rev = Convert(int, Substring(Packed, 1, 4)),
Description = Convert(varchar(100), Substring(Packed, 5, 100))
FROM
(
SELECT
ID,
Packed = Max(Convert(binary(4), Rev) + Convert(varbinary(100), Description))
FROM Table_A
GROUP BY ID
) X
Note: this last method is not recommended, but it's fun to simulate the First/Last aggregates in MS Access.
注意:不推荐使用最后一种方法,但模拟MS Access中的First / Last聚合很有趣。
#3
0
I would tend to favour the first approach - from a readability perspective, once you're comfortable with the ROW_NUMBER() OVER ... syntax then it's somewhat more readable. From a performance perspective, I would be surprised if there was much difference between the two - if there is then I would expect that the second would perform worse - but I stand to be corrected on that!
我倾向于赞成第一种方法 - 从可读性的角度来看,一旦你对ROW_NUMBER()OVER ...语法感到满意,那么它就会更具可读性。从性能的角度来看,如果两者之间存在很大差异,我会感到惊讶 - 如果有的话,我会期望第二个会表现更差 - 但我会立即予以纠正!
#1
1
The second approach looks like a SQL Server 2000 approach before Row_Number()
was introduced. This is the Greatest-n-per-group problem.
在引入Row_Number()之前,第二种方法看起来像SQL Server 2000方法。这是每组最大的问题。
To evaluate them you should look at the execution plans and the I/O Stats by running SET STATISTICS IO ON
要评估它们,您应该通过运行SET STATISTICS IO ON来查看执行计划和I / O统计信息
Of course for the specific example you have given the following would work equally well
当然,对于您给出以下内容的具体示例,同样可以正常工作
select TOP 1
ID
, Rev
, Description
from Table_A
Where ID = 1
ORDER BY Rev desc
#2
1
If you have a parent table with each ID listed only once, this can sometimes outperform other strategies including the row_number solution:
如果您有一个父表,每个ID只列出一次,这有时可以胜过其他策略,包括row_number解决方案:
SELECT
X.*
FROM
ParentTable P
CROSS APPLY (
SELECT TOP 1 *
FROM Table_A A
WHERE P.ID = A.ID
ORDER BY A.Rev DESC
) X
And the crazy, patented (just kidding), single scan magic query which can often outperform other methods as well:
而疯狂的,专利的(只是开玩笑),单扫描魔术查询,通常也可以胜过其他方法:
SELECT
ID,
Rev = Convert(int, Substring(Packed, 1, 4)),
Description = Convert(varchar(100), Substring(Packed, 5, 100))
FROM
(
SELECT
ID,
Packed = Max(Convert(binary(4), Rev) + Convert(varbinary(100), Description))
FROM Table_A
GROUP BY ID
) X
Note: this last method is not recommended, but it's fun to simulate the First/Last aggregates in MS Access.
注意:不推荐使用最后一种方法,但模拟MS Access中的First / Last聚合很有趣。
#3
0
I would tend to favour the first approach - from a readability perspective, once you're comfortable with the ROW_NUMBER() OVER ... syntax then it's somewhat more readable. From a performance perspective, I would be surprised if there was much difference between the two - if there is then I would expect that the second would perform worse - but I stand to be corrected on that!
我倾向于赞成第一种方法 - 从可读性的角度来看,一旦你对ROW_NUMBER()OVER ...语法感到满意,那么它就会更具可读性。从性能的角度来看,如果两者之间存在很大差异,我会感到惊讶 - 如果有的话,我会期望第二个会表现更差 - 但我会立即予以纠正!