sql查询各科成绩前三名----详述过程,思路清晰不烧脑
使用mysql、hive查询各科成绩前三名
- 一、建表造数据
- 二、使用myql查询
- 2.1 不考虑并列情况
- 方法一:使用加行号的方式查询
- 方法二:使用子查询嵌套查询(使用最多)
- 2.2 考虑并列情况
- 三、使用hive查询前三名
- 3.1 不考虑并列情况:rank()
- 3.2 考虑并列情况:dense_rank()
一、建表造数据
建表:
create table scores(
name varchar(100),
subject varchar(100),
score int
);
插入数据:
insert into scores values
('学生a','java','100'),
('学生b','java','90'),
('学生c','java','90'),
('学生d','java','60'),
('学生e','java','80'),
('学生a','python','100'),
('学生b','python','90'),
('学生c','python','90'),
('学生d','python','60'),
('学生e','python','80');
二、使用myql查询
2.1 不考虑并列情况
方法一:使用加行号的方式查询
加行号的使用规则是:@rowNum:=num
意思是声明一个叫 rowNum 的变量并赋值为num
示例: 现在有一个需求是: “查询学生 java 课的成绩、姓名并排名?”
select score,name,@m1:=@m1+1 r from scores,(select @m1:=0)a where subject='java' order by score desc
查询结果如下
此处加行号m1的作用就可以体现出来,查询语句中多了一个字段 r ,他可以以数字1,2,3,4,5的形式显示排名
由此引申,此条查询语句结尾在加上 limit 3 便可以取出前三名
select score,name,@m1:=@m1+1 r from scores,(select @m1:=0)a where subject='java' order by score desc limit 3
再引申,若要查询所有课程的成绩,取前三名,则就需要将其他的课程表 join 在一起,关联条件为每条查询语句的行号相等
select s1.score "java成绩",s1.name,s2.score "python成绩",s2.name,s1.r "排名" from
(select score,name,@m1:=@m1+1 r from scores,(select @m1:=0)a where subject='java' order by score desc limit 3)s1
join
(select score,name,@m2:=@m2+1 r from scores,(select @m2:=0)b where subject='python' order by score desc limit 3)s2
on s1.r=s2.r;
输出结果为:
这种方法查询实际上是 列转行 的方式,将字段subject 列 转成 行 输出。
优点 是容易理解,增加了一个字段显示排名,更加直观。
缺点 是在关联条件多(比如课程数量大于10,查询每科前10名,前20名成绩…)的情况下, join 关联10次以上,频繁的join会损耗系统很多性能,严重的会直接堵塞死。且有个弊端是写查询语句的时候必须要知道具体有几门课及课程名称,where 条件就已经限定了每门课的课程id或者课程名称,但有些情况下表数据量很大的时候,这种方法是不合适的。
方法二:使用子查询嵌套查询(使用最多)
select s1.* from scores s1
where (select count(1) from scores s2 where s1.subject=s2.subject and s1.score<s2.score)<3
order by s1.subject,s1.score desc;
查询结果如下:
这种方法比较难懂,但是查询速度快且代码简单,解析如下:
首先如果要查询所有课程的成绩,如下:
再对各科成绩倒序排列输出:
然后 取各科成绩前三名,就需要嵌套子查询进行筛选,代码如下:
select s1.* from scores s1
where (select count(1) from scores s2 where s1.subject=s2.subject and s1.score<s2.score)<3
order by s1.subject,s1.score desc;
查询语句重点在于 -->子查询语句: select count(1) from scores s2 where s1.subject=s2.subject and s1.score<s2.score
意思是:统计学生个数,即关联两个分数表s1、s2,外层查询每查询一次,再到内层循环中查询表s2,当课程名相同时,统计 s1.score<s2.score 即表s2中成绩大于s1的人数有几人。
这么说可能还是有点懵,现在我们来走一遍流程,从头到尾依次遍历一次,详细说明:
首先从学生a开始查询:
→学生b:
→学生c:
→学生d:
→学生e:
此时从学生a到e的 “java” 课程前三名已经筛选完成,对于 “python” 课程,重复上述流程即可
全部筛选完毕最后再对查询出的课程、分数倒序排列即可 :order by s1.subject,s1.score desc
2.2 考虑并列情况
select s1.name,s1.subject,s1.score from scores s1
left join (select distinct subject,score from scores) s2
on s1.subject=s2.subject
and s1.score<s2.score
group by s1.name,s1.subject,s1.score
having count(1)<3
order by subject,score desc;
查询结果如下:
很直观的可以看出,学生b和c成绩都为90分,并列第二名,学生e成绩80分,为第三名
查询语句解析:
这是在 2.1方法二 的基础上,使用 distinct 关键字对表s2中存在多名同学分数相同的情况进行 去重,从而达到并列排名的目的。需要注意的是,由于groub by 的条件是表s1中的字段,所以 count(1) 统计的是表s1中每次查询s1.score<s2.score 成绩低于表s2的学生人数,满足条件小于3,就可以取出前三名
三、使用hive查询前三名
使用hive查询需要调用 窗口函数,类似于 2.1方法一 中加行号查询,但使用不同的窗口函数可以实现并列与不并列的排名顺序
3.1 不考虑并列情况:rank()
select * from
(select name,subject,score,rank() over (partition by subject order by score desc) ranks from scores)s
where ranks<4;
查询结果如下:
3.2 考虑并列情况:dense_rank()
select * from
(select name,subject,score,dense_rank() over (partition by subject order by score desc) ranks from scores)s
where ranks<4;
查询结果如下:
sql查询各科成绩前三名----详述过程,思路清晰不烧脑相关推荐
- mysql查询各科成绩前三名的记录,sql查询各科成绩前三名----详述过程,思路清晰不烧脑...
使用mysql.hive查询各科成绩前三名 一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), scor ...
- sql查询各科成绩前三名----详述过程,思路清晰不烧脑!
一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), score int ); 插入数据: insert ...
- sql查询成绩最高分_sql查询各科成绩前三名----详述过程,思路清晰不烧脑!
一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), score int ); 插入数据: insert ...
- Mysql查询各科成绩前三名并分别排序
Mysql查询各科成绩前三名并分别排序 这个问题是之前1个朋友学mysql他们老师布置的作业,一开始我没有做过,而且刚出来做开发很多学过的东西都忘记了. 表结构如下: 一开始我是这样写的: selec ...
- MySQL 查询学生的总成绩并进行排名_MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况)...
MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况) MySQL查询各科成绩前三名的记录及排名(不考虑成绩并列情况) 我的表结构: 先放代码 -- 查询各科成绩前三名的记录(不考虑成绩并列情 ...
- mysql将多个成绩放在一排_mysql巧用连表查询各科成绩前三名
下列是各表的详情,不想自己建表的同学可以直接copy code,数据随意. 创建表成绩详情表: CREATE TABLE score ( id int(10) NOT NULL AUTO_INCREM ...
- mysql查询各科成绩前三名的记录_mysql巧用连表查询各科成绩前三名
下列是各表的详情,不想自己建表的同学可以直接copy code,数据随意. 创建表成绩详情表: CREATE TABLE score ( id int(10) NOT NULL AUTO_INCREM ...
- 查询各科成绩前3和第3的学生(SQL)
数据库面试题: 其他关联表这里不一一写出,仅写出关键表(score)成绩表 成绩记录id scoreid 学生id userid 课程id scoureid 成绩 score 现需要求出各科成绩前三名 ...
- sql统计各科成绩大于平均分的人_数据分析师SQL面试必备50题
以下是SQL面试必备的经典的50道题目,每道题都有博主本人的解题思路和对应的SQL语句. 每道题的思路与答案均为博主本人主观理解,仅供参考. 环境:MySQL8.0 可视化工具:Navicat 1.查 ...
- SQL查询——各科前三名的成绩(改良版)
SQL查询--各科前三名的成绩 表结构 查询代码 思路 小结 表结构 //临时表 cerate table id( id number ) //选课表 cerate table sc( sid num ...
最新文章
- DELL equallogic 的MPIO配置
- 城市“脑梗” 当前城市大脑面临的困境
- Cognizant:走向2028年将诞生的21个新工作
- CAD绘图软件中如何查询图纸的版本是多少
- day04-html
- SAP 库存物资收发存报表主要思路
- 杏树林孙文亮:在线医疗数据驱动实战
- java的编译器怎么出来_怎样掌握ava编译器的使用,教程在这里,如何进行Java初级学习...
- 跨进程实现在Tree中快速定位节点
- 使用多个tomcat如何修改端口号
- 小程序获取用户地址信息api
- python实现仿射变换
- python简单代码恶搞-一个可以套路别人的python小程序实例代码
- 模拟京东商城登陆HttpRequest
- 断网重启路由器就好_电脑老断网重启就好怎么解决
- jdk版本升级或降级
- 关系型数据库设计之从E-R图绘制到数据库表设计
- 计算机表格数据怎么样汇总,Excel 中如何汇总相同结构的多个工作表数据
- 单招计算机专业的自我介绍,单招面试三分钟自我介绍范文
- FME教程:GIS建筑面转CAD格式JMD,还原房屋建筑结构、层数、地物样式,shp转CAD,GIS转dwg
热门文章
- 谈谈两个互联网大佬的「认知革命」
- con和com开头单词规律_con和com的前缀区别。背单词时总是搞不清什么时候是con什么时候是com之后找到了不同之处,c...
- Preferences DataStore全解析
- apkg格式怎么打开_jpg怎么转换成pdf?再不学就晚了
- 银行卡四要素检测 API接口数据
- 保角变换法matlab编程,保角变换法.ppt
- 关于EPCS系列芯片的说明
- Anaconda中spyder5闪退如何解决
- ios13 自带字体列表
- 数据分析师工资水平怎么样?看看这些你就知道了