我有一种情况,对于SQL中低于阈值限制的值,我必须排名负数。有人可以帮我吗?
Name Target Rank
John 2500 -2
Hopkins 4000 -1
Paul 5000 0
Gracia 5200 1
以上是目标表的示例。我需要分配排名,如图所示。对于值5000的人,应将其分配为“ 0”。对于资源低于5000的资源,其排名应为负值(-1,-2,-3 ...)对于资源高于5000的资源,其排名应为正值(1,2,3)。 – enter image description here
答案 0 :(得分:4)
结合使用ROW_NUMBER()
和COUNT()
分析函数:
Oracle设置:
CREATE TABLE table_name ( Name, Target ) As
SELECT 'John', 2500 FROM DUAL UNION ALL
SELECT 'Hopkins', 4000 FROM DUAL UNION ALL
SELECT 'Paul', 5000 FROM DUAL UNION ALL
SELECT 'Gracia', 5200 FROM DUAL;
查询:
SELECT t.*,
ROW_NUMBER() OVER ( ORDER BY target ASC )
- COUNT( CASE WHEN target < 5000 THEN 1 END ) OVER ()
- 1 AS rnk
FROM table_name t;
输出:
NAME | TARGET | RNK :------ | -----: | --: John | 2500 | -2 Hopkins | 4000 | -1 Paul | 5000 | 0 Gracia | 5200 | 1
db <>提琴here
更新:
Oracle设置:
CREATE TABLE table_name ( Name, Target ) As
SELECT 'John', 2500 FROM DUAL UNION ALL
SELECT 'Hopkins', 4000 FROM DUAL UNION ALL
SELECT 'Bob', 5000 FROM DUAL UNION ALL
SELECT 'Smith', 5000 FROM DUAL UNION ALL
SELECT 'Paul', 5100 FROM DUAL UNION ALL
SELECT 'Janet', 5100 FROM DUAL UNION ALL
SELECT 'Gracia', 5200 FROM DUAL;
查询1 :如果您希望每行唯一的排名,并且如果值不为5000,则不希望排名为0的行:
SELECT t.*,
ROW_NUMBER() OVER ( ORDER BY target ASC, name ASC )
- COUNT( CASE WHEN target < 5000 THEN 1 END ) OVER ()
- CASE WHEN target > 5000 AND COUNT( CASE WHEN target = 5000 THEN 1 END ) OVER () = 0 THEN 0 ELSE 1 END AS rnk
FROM table_name t;
输出:
NAME | TARGET | RNK :------ | -----: | --: John | 2500 | -2 Hopkins | 4000 | -1 Bob | 5000 | 0 Smith | 5000 | 1 Janet | 5100 | 2 Paul | 5100 | 3 Gracia | 5200 | 4
查询2 :如果您希望具有相同目标的行具有相同的等级,并且仅具有5000个目标的行的等级为0:
SELECT name,
target,
DENSE_RANK() OVER ( ORDER BY target ASC )
- COUNT( CASE WHEN target < 5000 AND rn = 1 THEN 1 END ) OVER ()
- CASE WHEN target > 5000 AND COUNT( CASE WHEN target = 5000 AND rn = 1 THEN 1 END ) OVER () = 0 THEN 0 ELSE 1 END AS rnk
FROM (
SELECT t.*,
ROW_NUMBER() OVER ( PARTITION BY target ORDER BY name ) AS rn
FROM table_name t
);
输出:
NAME | TARGET | RNK :------ | -----: | --: John | 2500 | -2 Hopkins | 4000 | -1 Bob | 5000 | 0 Smith | 5000 | 0 Janet | 5100 | 1 Paul | 5100 | 1 Gracia | 5200 | 2
db <>提琴here
答案 1 :(得分:2)
这是您的要求的重要转载。
您有三种不同情况的target
,因此您设置了一个case
,其中三个分支计算了RANK
。
您可以使用常规的RANK
聚合分析功能,但从技术上讲,您必须在三种情况下PARTITION BY
。
select NAME, TARGET,
case when target = 5000 then 0
when target > 5000 then RANK()
over (partition by case when target > 5000 then 1 when target < 5000 then -1 else 0 end
order by target)
when target < 5000 then - RANK()
over (partition by case when target > 5000 then 1 when target < 5000 then -1 else 0 end
order by - target)
end as rank
from tab;
NAME TARGET RANK
------- ---------- ----------
John 2500 -2
Hopkins 4000 -1
Paul 5000 0
Gracia 5200 1