ROW_NUMBER() OVER()函数用法详解

Posted 高高for 循环

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ROW_NUMBER() OVER()函数用法详解相关的知识,希望对你有一定的参考价值。

ROW_NUMBER() OVER()函数

使用范围:

  • 这个函数可以Oracle中使用
  • mysql用不了

语法格式:

row_number() over(partition by 分组列 order by 排序列 desc)

注意:

  • 在使用 row_number() over()函数时候,over()里头的分组以及排序的执行晚于 where 、group by、 order by 的执行。

案例 1

表数据:

create table TEST_ROW_NUMBER_OVER(
       id varchar(10) not null,
       name varchar(10) null,
       age varchar(10) null,
       salary int null
);
select * from TEST_ROW_NUMBER_OVER t;
 
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a',10,8000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(1,'a2',11,6500);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b',12,13000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(2,'b2',13,4500);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c',14,3000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(3,'c2',15,20000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(4,'d',16,30000);
insert into TEST_ROW_NUMBER_OVER(id,name,age,salary) values(5,'d2',17,1800);

一次排序:对查询结果进行排序(无分组)

SELECT id,NAME,age,salary,row_number()over(ORDER BY salary DESC) rank
FROM TEST_ROW_NUMBER_OVER t

进一步排序:根据id分组排序

select id,name,age,salary,row_number()over(partition by id order by salary desc) rank
from TEST_ROW_NUMBER_OVER t

再一次排序:找出每一组中序号为一的数据

SELECT * FROM(SELECT id,NAME,age,salary,row_number()over(PARTITION BY id ORDER BY salary DESC) rank
FROM TEST_ROW_NUMBER_OVER ) t
WHERE rank <2

排序找出年龄在13岁到16岁数据,按salary排序

select id,name,age,salary,row_number()over(order by salary desc)  rank
from TEST_ROW_NUMBER_OVER t where age between '13' and '16'

结果:结果中 rank 的序号,其实就表明了 over(order by salary desc) 是在where age between and 后执行的

案例 2

表数据:

  • 创建学生成绩表
  • 班级信息表
  • 并插入测试数据
/*-创建学生成绩表-*/
CREATE TABLE StuScore
(
	StuID INT,            
	StuName VARCHAR(20),  
	ClassID INT,          
	SUBJECT VARCHAR(20), 
	Score INT             
);
 
/*-创建班级信息表-*/
CREATE TABLE ClassInfo
(
	ClassID INT,           
	ClassName VARCHAR(20)
);
 
/*-添加学生成绩信息-*/
INSERT INTO StuScore VALUES(1,'张三',1,'语文',60);
INSERT INTO StuScore VALUES(1,'张三',1,'数学',90);
INSERT INTO StuScore VALUES(1,'张三',1,'英语',70);
INSERT INTO StuScore VALUES(2,'李四',2,'语文',100);
INSERT INTO StuScore VALUES(2,'李四',2,'数学',90);
INSERT INTO StuScore VALUES(3,'王五',2,'语文',80);
 
/*-添加班级信息-*/
INSERT INTO ClassInfo VALUES(1,'高一(1)班');
INSERT INTO ClassInfo VALUES(2,'高二(3)班');


按学生成绩排序,并为每条排序后的记录返回一个序号

SELECT ROW_NUMBER() OVER(ORDER BY Score DESC) AS Row_Index,* 
FROM StuScore

按学生编号(StuID)分组,且按学生成绩排序,再为每条排序后的记录返回一个序号


SELECT ROW_NUMBER() OVER(PARTITION BY StuID ORDER BY Score DESC) AS Row_Index,* 
FROM StuScore

查询每个学生最高的成绩

SELECT t.* FROM(
	SELECT ROW_NUMBER() OVER(PARTITION BY StuID ORDER BY Score DESC) AS Row_Index,* 
	FROM StuScore
) t WHERE t.Row_Index = 1


查询每个学生最高的成绩,并关联班级名称。

SELECT t1.StuID,t1.StuName,t1.Subject,t1.Score,t2.ClassName FROM(
	SELECT tt.* FROM(
		SELECT ROW_NUMBER() OVER(PARTITION BY StuID ORDER BY Score DESC) AS Row_Index,* 
		FROM StuScore
	) tt WHERE tt.Row_Index = 1) t1
LEFT JOIN ClassInfo t2 ON t1.ClassID = t2.ClassID

以上是关于ROW_NUMBER() OVER()函数用法详解的主要内容,如果未能解决你的问题,请参考以下文章

ROW_NUMBER() OVER() 函数用法详解 (分组排序,多例子)

Oracle中ROW_NUMBER() OVER()函数用法

ROW_NUMBER() OVER函数的基本用法

ROW_NUMBER() OVER()函数用法;(分组,排序),partition by

ROW_NUMBER() OVER()函数用法;(分组,排序),partition by

ROW_NUMBER() OVER()函数用法;(分组,排序),partition by