使用Rank vs Max(T-SQL)

时间:2013-01-16 15:16:50

标签: sql tsql sql-server-2008-r2

我目前正致力于排除运行查询需要很长时间的旧作业。旧作业使用第一个查询,但我一直在使用第二个查询进行测试。

之间的差异:

Select Max(Cl1) as Tab,
       Max(Cl2) as Tb,
       Customer
From TableA
group by Customer

VS

Select Customer,
       Tab,
       tb
From 
(Select Customer,
         Tab,
         tb,
         Rank() over (partition by Customer order by Cl1 desc) rk1,
         Rank() over (partition by Customer order by Cl2 desc) rk2
  From TableA) X
 Where X.rk1 = 1 and X.rk2 = 1

Tab Tb Customer

A45845 100052 Shin

A45845 100053 Shin

A45845 100054 Reek

对于Tab和Tb列,表始终具有值(无空值或空值)。选项卡不是特定客户的唯一选择。 Tb是一个连续且连续增加的整数,不可能有重复(唯一)。客户的最新Tab值也将具有最新的Tb。

虽然结果是一样的,但是在这种情况下更改查询时我可能没有考虑过吗?

编辑:修复构建示例并且不使用实际列或表名称时第二个查询的错误。还介绍了情景。我对原始帖子中的更新信息和修复道歉,在我甚至有机会仔细检查之前就被调用了。

3 个答案:

答案 0 :(得分:0)

第一个查询返回TabTb的值,第二个查询总是为两列返回1和1(因为where子句)。

第二个只会返回CL1和Cl2都是第一行的客户。第一个为所有客户返回一行。

当多行满足给定客户的两个排序条件时,第二个将返回重复项。第一个每个客户只返回一行。

第二个语法有错误,因此无法运行(rk2之后的逗号)。第一个似乎是有效的SQL语法。

第一个似乎更简单,更容易理解。但是,我认为我的第一点是最大的不同。 (我忽略了这些列的顺序不同。)

答案 1 :(得分:0)

这将是等价查询,但我怀疑它会更有效率。 @Damien_The_Unbeliever如果我错了,请告诉我。 (对于存在多个具有相同值的Cl1和Cl2行的情况添加了区别。如果主键跨越客户,Cl1和Cl2,则可以删除。)

Select  Distinct Customer,
        X.Cl1 as Tab,
        X2.Cl2 as tb
From   (Select  Customer,
                Rank() over (partition by Customer order by Cl1 desc) rk1, 
                Cl1
        From    TableA) X
Join   (Select  Customer,         
                Rank() over (partition by Customer order by Cl2 desc) rk2, 
                Cl2
        From    TableA) X2
        On  X.Customer = X2.Customer
Where   X.rk1 = 1 
And     X2.rk2 = 1

答案 2 :(得分:0)

严重怀疑Rank会更快。

如果您想在CL1最大的行上获得CL2的值,那么您需要排名的位置。

您对Customer,CL1和CL2有索引吗?
检查碎片。
检查执行计划。

并且这些结果不会返回相同的结果。