我的查询具有以下结构:
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%,其他项目应根据其排名显示。
答案 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;