首页 > 数据库 >SQL中的排名问题

SQL中的排名问题

时间:2023-06-07 17:01:22浏览次数:39  
标签:students SQL RANK 问题 score 数学 scores 排名 id

SQL中的排名问题

一、模拟学生成绩数据

1.1 创建学生表

首先,我们创建一个名为 "students" 的表来存储学生信息:

CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(50),
  age INT
);

1.2 创建分数表

然后,我们创建一个名为 "scores" 的表来存储学生成绩:

CREATE TABLE scores (
  id INT PRIMARY KEY,
  student_id INT,
  subject VARCHAR(50),
  score INT,
  FOREIGN KEY (student_id) REFERENCES students(id)
);

1.3 维护学生表和分数表数据

接下来,我们向 "students" 表插入一些示例数据:

INSERT INTO students (id, name, age)
VALUES
  (1, '张三', 18),
  (2, '李四', 19),
  (3, '王五', 20),
  (4, '赵六', 19);

然后,我们向 "scores" 表插入一些示例数据:

INSERT INTO scores (id, student_id, subject, score)
VALUES
  (1, 1, '数学', 90),
  (2, 1, '语文', 85),
  (3, 1, '英语', 92),
  (4, 2, '数学', 90),
  (5, 2, '语文', 78),
  (6, 2, '英语', 85),
  (7, 3, '数学', 95),
  (8, 3, '语文', 92),
  (9, 3, '英语', 88),
  (10, 4, '数学', 82),
  (11, 4, '语文', 90),
  (12, 4, '英语', 85);

1.4 join查询

现在,我们已经创建了一个包含学生信息和成绩的学生成绩表。你可以根据自己的需要对表中的数据进行查询和操作。

例如,如果你想查询所有学生的成绩,可以使用以下 SQL 语句:

SELECT students.name, scores.subject, scores.score
FROM students
JOIN scores ON students.id = scores.student_id;

这将返回一个包含学生姓名、科目和成绩的结果集。

name subject score
张三 数学 90
张三 语文 85
张三 英语 92
李四 数学 90
李四 语文 78
李四 英语 85
王五 数学 95
王五 语文 92
王五 英语 88
赵六 数学 82
赵六 语文 90
赵六 英语 85

二、排名问题

排名中经常用到的ROW_NUMBER()RANK()DENSE_RANK()NTILE()这四个窗口函数。

以下使用模拟出的学生分数表数据分析其中一科的分数排名(分析数学成绩),数学分数结果:

SELECT students.name, scores.subject, scores.score
FROM students
JOIN scores ON students.id = scores.student_id
WHERE scores.subject = '数学';
name subject score
张三 数学 90
李四 数学 90
王五 数学 95
赵六 数学 82

2.1 ROW_NUMBER()

定义ROW_NUMBER()函数作用就是将SELECT查询到的数据进行排序,每一条数据加一个序号,他不能用做于学生成绩的排名,一般多用于分页查询,比如查询前10个 查询10-100个学生。

使用该函数进行排名,当分数一致的时候,排名不会出现重叠,排名次序是唯一的。

2.1.1 对学生成绩排序

WITH t AS (
	SELECT
		students.NAME,
		scores.SUBJECT,
		scores.score 
	FROM
		students
		JOIN scores ON students.id = scores.student_id 
	WHERE
		scores.SUBJECT = '数学'
) SELECT ROW_NUMBER() OVER (ORDER BY score DESC) AS 'rank',t.* FROM t;

降序排名后结果:

rank name subject score
1 王五 数学 95
2 张三 数学 90
3 李四 数学 90
4 赵六 数学 82

2.1.2 获取第2名的成绩信息

WITH t AS (
	SELECT
		students.NAME,
		scores.SUBJECT,
		scores.score 
	FROM
		students
		JOIN scores ON students.id = scores.student_id 
	WHERE
		scores.SUBJECT = '数学'
) 
SELECT * FROM (SELECT ROW_NUMBER() OVER (ORDER BY score DESC) AS 'rank',t.* FROM t) AS tb WHERE tb.rank = 2;

结果:

rank name subject score
2 张三 数学 90

2.2 RANK()

RANK()函数,顾名思义排名函数,可以对某一个字段进行排名,这里和ROW_NUMBER()有什么不一样呢?

ROW_NUMBER()是排序,当存在相同成绩的学生时,ROW_NUMBER()会依次进行排序,他们序号不相同,而Rank()则不一样。如果出现相同的,他们的排名是一样的。

示例

WITH t AS (
	SELECT
		students.NAME,
		scores.SUBJECT,
		scores.score 
	FROM
		students
		JOIN scores ON students.id = scores.student_id 
	WHERE
		scores.SUBJECT = '数学'
) SELECT RANK() OVER (ORDER BY score DESC) AS 'rank',t.* FROM t;

降序排序名结果:

rank name subject score
1 王五 数学 95
2 张三 数学 90
2 李四 数学 90
4 赵六 数学 82

2.1.1中的结果是ROW_NUMBER()函数的结果,上面的是RANK()函数的结果。

当出现两个学生成绩相同是里面出现变化。RANK()排名后是1-2-2-4,而ROW_NUMBER()则还是1-2-3-4

2.3 DENSE_RANK()

DENSE_RANK()函数也是排名函数,和RANK()功能相似,也是对字段进行排名,那它和RANK()到底有什么不同那?

特别是对于有成绩相同的情况,DENSE_RANK()排名是连续的,RANK()是跳跃的排名,一般情况下用的排名函数就是RANK()

示例

WITH t AS (
	SELECT
		students.NAME,
		scores.SUBJECT,
		scores.score 
	FROM
		students
		JOIN scores ON students.id = scores.student_id 
	WHERE
		scores.SUBJECT = '数学'
) SELECT DENSE_RANK() OVER (ORDER BY score DESC) AS 'rank',t.* FROM t;

降序排名后结果:

rank name subject score
1 王五 数学 95
2 张三 数学 90
2 李四 数学 90
3 赵六 数学 82

2.2中的结果是RANK()的结果,上面的结果是DENSE_RANK()的结果。

2.4 NTILE()

在 SQL 中,NTILE 函数用于将一个结果集分成指定数量的桶(buckets)或分组,并将每个行分配到对应的桶中。这可以用于数据分析、分组统计和排名等场景。

WITH t AS (
	SELECT
		students.NAME,
		scores.SUBJECT,
		scores.score 
	FROM
		students
		JOIN scores ON students.id = scores.student_id 
	WHERE
		scores.SUBJECT = '数学'
) SELECT ntile(2) OVER (ORDER BY score DESC) AS 'rank',t.* FROM t;

分区后的结果:

rank name subject score
1 王五 数学 95
1 张三 数学 90
2 李四 数学 90
2 赵六 数学 82

就是将查询出来的记录根据NTILE函数里的参数进行平分分区。

标签:students,SQL,RANK,问题,score,数学,scores,排名,id
From: https://www.cnblogs.com/itelephant/p/17463892.html

相关文章

  • 创建NuGet本地包的问题:【LocalNugGet】未将对象引用设置到对象的实例
    现象:创建NuGet本地包后,使用NuGet管理器访问LocalNuGet时,报错:【LocalNugGet】未将对象引用设置到对象的实例检查C:\Users{此处时你的用户名}\AppData\Roaming\NuGet路径下的NuGet.Config配置文件。发现:LocalNuGet名字有重复出现。LocalNuGet后面有参数:protocolVersion......
  • jest 问题集
    error:...isnotaconstructorreason:Themockcan'tbeanarrowfunctionbecausecallingnewonanarrowfunctionisnotallowedinJavaScript.ref:https://jestjs.io/docs/es6-class-mocks#manual-mock-that-is-another-es6-classerror:Matchererror:......
  • Mysql union all+括号引起的性能问题
    SQL如下(MYSQL版本为8.0.17):selectlastnamefrom(selectid,loginid,workcode,lastnamefromHrmResourceunionallselectid,loginid,''asworkcode,lastnamefromHrmResourceManager) a  where(idin(83109));mysql>explainselectlastnamefrom(s......
  • 解决Ubuntu 20.04升级后gnome-control-center设置程序无法打开问题
    解决Ubuntu20.04升级后gnome-control-center设置程序无法打开问题Ubuntu20.04系统升级后,发现gnome设置程序无法正常打开了。在终端运行命令查看错误信息,运行以下命令:sudognome-control-center从显示的错误信息可以看出,其调用的一些so文件,需要高版本的libc6,而Ubuntu20.0......
  • mysql 慢查询的简要介绍
    如何配置与查看慢查询mysql慢查询相关命令:#查看慢查询是否开启SHOWVARIABLESLIKE'%slow_query_log%'#开启慢查询SETGLOBALslow_query_log='ON'#查看慢查询日志位置SHOWVARIABLESLIKE'%slow_query_log_file%'#查看慢查询阈值,单位:秒SHOWGLOBALVARIABLES......
  • 奇安信设备问题(初中级)
    一、天眼设备1、在天眼设备中,sip、dip、sport、dport字段的含义?答:sip是源IP、dip是目的IP;sport是源端口、dport是目的端口。2、在天眼分析平台DNS协议中的dnstype字段的含义是什么?答:dnstype表示DNS请求类型;0表示DNS请求、1表示DNS响应。3、dns_type中的addr代表什么?答:表示......
  • 微信小程序输入框光标错乱问题
     会出现这个问题,一般是受到了滚动条的影响,所以,在获取焦点时,需要关闭页面滚动,失去焦点时,就开启滚动,例如页面里存在scroll-view组件示例代码wxml片段<scroll-viewclass="m_scroll"style="height:100vh;"scroll-y="{{aFocus}}"scroll-with-animation></scroll-view><in......
  • SQL Server 补丁理解及安装 内附完整版下载地址及sp1/2/3补丁
    启动安装程序下载sqlserver2014,双击startup.exe进行安装 系统配置检查器 使用系统配置检查器,看系统是否符合安装sqlserver2014的所有要求 开始安装然后点击安装,全新sqlserver独立安装或向现有安装添加功能 安装规则然后就是使用默认的设置,点开详细信息,可以看到安......
  • mysql-编写脚本-批量插入数据
    一、代码--报工设置,添加数据set@org_id='租户id';set@created_user='yike';set@updated_user='yike';set@dispatch_list_id=<物料id>;set@process_name='工序名称';set@process_code='工序code';set@code=&......
  • sqlserver2014在新建维护计划时提示代理XP组件已做为此服务器安全配置的一部分被关闭,
     在sqlserver配置管理器中打开sqlserver代理即可 ......