在不使用解析函数的情况下实现 Rank
Implement Rank without using analytic function
我想知道是否有一种方法可以在不使用内置函数的情况下实现 SQL 分析函数。
SELECT *,
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rownum,
DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS denserank,
RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM emp;
您可以使用相关的子查询来做到这一点。
select dept_id,salary,
(select count(*) from emp e1 where e1.dept_id=e.dept_id and e1.salary>=e.salary) as rnum
from emp e
当没有关系时,这很有效。
下面是三个等价的表达式:
select emp.*,
(select count(*)
from emp emp2
where emp2.dept_id = emp.dept_id and
(emp2.salary > emp.salary or
emp2.salary = emp.salary and emp2.emp_id <= emp.emp_id
)
) as "row_number",
(select 1 + count(*)
from emp emp2
where emp2.dept_id = emp.dept_id and
emp2.salary > emp.salary
)
) as "rank",
(select count(distinct salary)
from emp emp2
where emp2.dept_id = emp.dept_id and
emp2.salary >= emp.salary
) as "dense_rank",
from emp;
这假定存在 emp_id
以使行对 "row_number" 唯一。
这适用于所有情况
select DEPT_ID, SALARY,
(select count(*)+1 from emp r where r.SALARY>o.SALARY and r.dept_id=o.dept_id) **rank**,
(select count(distinct SALARY )+1 from emp r where r.SALARY>o.SALARY and r.dept_id=o.dept_id) *d_rank*,
(select count(*)+1 from (select x.*,rownum rn from ( select emp.* from emp order by DEPT_ID asc,salary desc ) x) r where r.rn<o.rn and r.dept_id=o.dept_id) **rownumm**
from (select x.*,rownum rn from ( select emp.* from emp order by DEPT_ID asc,salary desc ) x) o
order by DEPT_ID,salary desc;
对于排名:- 使用((小于当前行的值的计数)+1
计算
对于密集排名:- 与排名相同(计数小于当前行的不同值)+1
row_number:- 通过为每一行生成 rownum 来创建嵌套查询,这对于所有行都是不同的。现在最重要的是执行与排名相同的逻辑
(大于前一个行数的值计数(select 子查询的行数))+1
我想知道是否有一种方法可以在不使用内置函数的情况下实现 SQL 分析函数。
SELECT *,
ROW_NUMBER() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rownum,
DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS denserank,
RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rnk
FROM emp;
您可以使用相关的子查询来做到这一点。
select dept_id,salary,
(select count(*) from emp e1 where e1.dept_id=e.dept_id and e1.salary>=e.salary) as rnum
from emp e
当没有关系时,这很有效。
下面是三个等价的表达式:
select emp.*,
(select count(*)
from emp emp2
where emp2.dept_id = emp.dept_id and
(emp2.salary > emp.salary or
emp2.salary = emp.salary and emp2.emp_id <= emp.emp_id
)
) as "row_number",
(select 1 + count(*)
from emp emp2
where emp2.dept_id = emp.dept_id and
emp2.salary > emp.salary
)
) as "rank",
(select count(distinct salary)
from emp emp2
where emp2.dept_id = emp.dept_id and
emp2.salary >= emp.salary
) as "dense_rank",
from emp;
这假定存在 emp_id
以使行对 "row_number" 唯一。
这适用于所有情况
select DEPT_ID, SALARY,
(select count(*)+1 from emp r where r.SALARY>o.SALARY and r.dept_id=o.dept_id) **rank**,
(select count(distinct SALARY )+1 from emp r where r.SALARY>o.SALARY and r.dept_id=o.dept_id) *d_rank*,
(select count(*)+1 from (select x.*,rownum rn from ( select emp.* from emp order by DEPT_ID asc,salary desc ) x) r where r.rn<o.rn and r.dept_id=o.dept_id) **rownumm**
from (select x.*,rownum rn from ( select emp.* from emp order by DEPT_ID asc,salary desc ) x) o
order by DEPT_ID,salary desc;
对于排名:- 使用((小于当前行的值的计数)+1
计算对于密集排名:- 与排名相同(计数小于当前行的不同值)+1
row_number:- 通过为每一行生成 rownum 来创建嵌套查询,这对于所有行都是不同的。现在最重要的是执行与排名相同的逻辑 (大于前一个行数的值计数(select 子查询的行数))+1