带有条件的T-SQL Rank()

时间:2016-05-24 15:48:53

标签: sql-server

我的查询具有以下结构:

    Value 1  Value 2
    100%         500
     90%         300
     89%         800
     95%         400

我需要按值2对结果进行排名,但前提是值1>> = 95%。

我该怎么做?我尝试使用以下方法解决问题:

CASE WHEN [Value 1] >= 95% 
THEN RANK() OVER (ORDER BY [Value 2] DESC)
END

对于不符合条件的行,该函数显示NULL,但即使在空白行上,排名顺序也会递增。

    Value 1  Value 2  Ranking
     89%         800  NULL
    100%         500  2
     95%         400  3
     90%         300  NULL

正确的结果应该是:

        Value 1  Value 2  Ranking
         89%         800  NULL
        100%         500  1
         95%         400  2
         90%         300  NULL

第一项和最后一项没有排名,因为两者都低于95%,其他项目应根据其排名显示。

3 个答案:

答案 0 :(得分:1)

您需要在PARTITION BY功能中添加RANK(),如下所示:

SELECT 
    v1, 
    v2, 
    CASE 
        WHEN v1 >= 95 
        THEN RANK() OVER (
            PARTITION BY CASE WHEN v1 >= 95 THEN 1 ELSE 2 END
            ORDER BY v2 DESC) 
      END AS Ranking
FROM (VALUES (100, 500), (90, 300), (89,800), (95,400)) AS Value(v1, v2)

原因是RANK()函数正在查看查询返回的所有行,而不仅仅是CASE表达式计算的行。通过向PARTITION BY添加相同的表达式,这实际上会将行排在两个不同的组中,即符合条件的组(>= 95)和不符合条件的组。

这会按照您的意愿公开排名。

答案 1 :(得分:0)

根据您想要的值小于95%的结果,您可以尝试这样的事情。根据您Value1的存储方式,可能需要稍微调整一下。

case when value1 > 95 then 
     rank() over (order by case when Value1 > 95 then 1 else 100 end
                  , Value2)
end

这会导致较低的值排序到排名的底部。

答案 2 :(得分:0)

感谢您使用所需的输出更新您的问题...以下内容将会执行此操作:

;With Ranking as (
    SELECT  v1, v2, RANK() OVER (ORDER BY v2 DESC) as Ord
    FROM (VALUES (1.00, 500), (.90, 300), (.89,800), (.95,400)) AS Value(v1, v2)
)
select  r.v1, r.v2, case when v1 >= .95 then r.Ord end Ord
from    Ranking r
order by r.Ord;