我创建了一个包含以下记录的emp表。
create table emp(
EMPNO integer,
EMPNAME varchar2(20),
SALARY number);
select * from emp;
empno empname salary
10 bill 2000
11 bill 2000
12 mark 3000
12 mark 3000
12 mark 3000
12 philip 3000
12 john 3000
13 tom 4000
14 tom 4000
14 jerry 5000
14 matt 5000
15 susan 5000
要删除重复项,我一直在使用rownum()函数以及partition by和order by子句,查询如下:
delete from emp where rowid in
(
select rid from
(
select rowid rid,
row_number() over(partition by empno order by empno) rn
from emp
)
where rn > 1
);
--6 rows deleted
查询删除所有具有重复empno的员工记录,结果看起来像这样:
empno empname salary
10 bill 2000
11 bill 2000
12 mark 3000
13 tom 4000
14 tom 4000
15 susan 5000
当我使用内部查询来获取表中所有结果的rownumbers时,它给出了以下结果:
select rowid as rid,empno,empname,
row_number() over(partition by empno order by empno) rn
from emp;
rowid rownumber
AACDJUAAPAAGLlTAAA 10 bill 1
AACDJUAAPAAGLlTAAB 11 bill 1
AACDJUAAPAAGLlTAAE 12 mark 1
AACDJUAAPAAGLlTAAD 12 mark 2
AACDJUAAPAAGLlTAAC 12 mark 3
AACDJUAAPAAGLlTAAF 12 philip 4
AACDJUAAPAAGLlTAAG 12 john 5
AACDJUAAPAAGLlTAAH 13 tom 1
AACDJUAAPAAGLlTAAI 14 tom 1
AACDJUAAPAAGLlTAAJ 14 jerry 2
AACDJUAAPAAGLlTAAK 14 matt 3
AACDJUAAPAAGLlTAAL 15 susan 1
但是当我使用rank()代替rownumber()函数时,它给出了以下结果:
select rowid as rid,empno,empname,
rank() over(partition by empno order by empno) rn
from emp;
rowid rank
AACDJUAAPAAGLlTAAA 10 bill 1
AACDJUAAPAAGLlTAAB 11 bill 1
AACDJUAAPAAGLlTAAE 12 mark 1
AACDJUAAPAAGLlTAAD 12 mark 1
AACDJUAAPAAGLlTAAC 12 mark 1
AACDJUAAPAAGLlTAAF 12 philip 1
AACDJUAAPAAGLlTAAG 12 john 1
AACDJUAAPAAGLlTAAH 13 tom 1
AACDJUAAPAAGLlTAAI 14 tom 1
AACDJUAAPAAGLlTAAJ 14 jerry 1
AACDJUAAPAAGLlTAAK 14 matt 1
AACDJUAAPAAGLlTAAL 15 susan 1
所以我的问题是为什么rank()给表中的所有记录赋予相同的值,即使有重复的empid?
答案 0 :(得分:3)
这就是RANK()
的工作方式。在分区中为等排行获取不同的RANK
值会相当令人惊讶。事实上,ORDER BY
子句是分区内RANK
的重要驱动因素,但由于您对分区使用相同的列和排序,因此很明显每行都有首先在他们各自的分区内(因为他们是分区中唯一的值)
See an explanation in this blog post,这个SQL(PostgreSQL语法)
SELECT
v,
ROW_NUMBER() OVER (window) row_number,
RANK() OVER (window) rank,
DENSE_RANK() OVER (window) dense_rank
FROM t
WINDOW window AS (ORDER BY v)
ORDER BY v
...产生此输出
+---+------------+------+------------+
| V | ROW_NUMBER | RANK | DENSE_RANK |
+---+------------+------+------------+
| a | 1 | 1 | 1 |
| a | 2 | 1 | 1 |
| a | 3 | 1 | 1 |
| b | 4 | 4 | 2 |
| c | 5 | 5 | 3 |
| c | 6 | 5 | 3 |
| d | 7 | 7 | 4 |
| e | 8 | 8 | 5 |
+---+------------+------+------------+
答案 1 :(得分:2)
有三种“排名”分析函数:row_number()
,rank()
和dense_rank()
。
这些都非常相似。它们按顺序将数字分配给组内的行。该组由partition by
子句定义。排序由order by
子句定义。三者之间的区别在于它们如何处理重复值。
row_number()
始终返回组内的序号。当存在联系时,等值行具有连续值,但它们是不同的。
dense_rank()
分配顺序值,没有间隙。但是,等值行被赋予相同的值。下一个值有一个等级。
rank()
使用间隙分配顺序值。等值行具有相同的值,但后续行有间隙。
以下是一个例子:
value row_number dense_rank rank
a 1 1 1
b 2 2 2
b 3 2 2
b 4 2 2
c 5 3 5
d 6 4 6
d 7 4 6