一、建表造数据

建表:

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
1

查询结果如下

此处加行号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查询成绩最高分_sql查询各科成绩前三名----详述过程,思路清晰不烧脑!相关推荐

  1. mysql查询各科成绩前三名的记录,sql查询各科成绩前三名----详述过程,思路清晰不烧脑...

    使用mysql.hive查询各科成绩前三名 一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), scor ...

  2. sql查询各科成绩前三名----详述过程,思路清晰不烧脑!

    一.建表造数据 建表: create table scores( name varchar(100), subject varchar(100), score int ); 插入数据: insert ...

  3. 数据库查询求小于_SQL查询应用总结

    一. 模糊查询 知识点: like %表示任意字符串 1. 查询姓'猴'的学生名单 猴% 2.查询姓名中最后一个字是'猴'的学生名单 %猴 3. 查询姓名中带'猴'的学生名单 %猴% 4.查询姓&qu ...

  4. esp32查询剩余内存_SQL 查询语句先执行 SELECT?兄弟你认真的么?

    SQL 查询的执行顺序是怎样呢? 好像这个问题应该很好回答,毕竟自己已经写了无数个 SQL 查询了,有一些还很复杂的. 但事实是,这个问题小编很难确切地说出它的顺序是怎样的. 言归正传,SELECT语 ...

  5. mysql语言中子查询是什么_SQL查询语句中,什么叫子查询?

    展开全部 嵌套SELECT语句也叫子查询,一个 SELECT 语句的查询结果能够作为另一个语句的输入值.子查询不但能够出现在Where子句3231313335323631343130323136353 ...

  6. sql查询每科成绩的最高分_SQL查询语句: 查询 每科目分数最高的5项(学生姓名,科目,分数)...

    SQL查询语句: 查询 每科目分数最高的5项(学生姓名,科目,分数) 关注:251  答案:4  mip版 解决时间 2021-01-10 16:21 已解决 2021-01-09 22:40 SQL ...

  7. sql查询每科成绩的最高分_SQL查询每科分数最高的

    假设数据表 examinationiɡ 有以下数据:+----+------+---------+--------+ | id | name | subject | number | +----+-- ...

  8. mysql求每个班级的最高分_sql查询每个班上成绩最高的学生信息

    sql查询每个班上成绩最高的学生信息 数据库表和数据准备: if exists (select * from sysobjects where id = OBJECT_ID('[classinfo]' ...

  9. sql server排序慢_SQL 查询调优之 where 条件排序字段以及 limit 使用索引的奥秘

    (给数据分析与开发加星标,提升数据技能) 作者:风过无痕-唐 www.cnblogs.com/tangyanbo/p/6378741.html 奇怪的慢sql 我们先来看2条sql 第一条: sele ...

最新文章

  1. sqrt()函数的详解和用法
  2. php zval_copy_static_var(),zval _ 引用计数 _ 变量分离 _ 写时拷贝
  3. codevs原创抄袭题 5960 信使
  4. [转]大数据环境搭建步骤详解(Hadoop,Hive,Zookeeper,Kafka,Flume,Hbase,Spark等安装与配置)
  5. IE6PNG8PNG24test
  6. (二分)Trailing Zeroes (III)
  7. 等概率随机函数的实现(对立事件的产生)
  8. Kafka自动提交offset设置
  9. docker版 Transmission以及qbittorrent 下载路径没有权限问题
  10. zebradesginer zpl代码_ZebraDesigner Pro 斑马打印机命令 解读
  11. shell小技巧(五)把以abc开头的下一行以def结尾的两行替换成douyu
  12. 00001__伊丽莎白福尔摩斯
  13. xp计算机无法正常启动,Windows XP电脑开机出错无法正常启动的解决方法
  14. ubuntu 中 vi 编辑文件上下左右删除键毫无作用肿么办!(上上下下左右左右BABA)
  15. js实现电子签名功能
  16. Scan Context回环检测解读和使用
  17. 一个简单的微分对策问题求解及其Matlab实现
  18. 小学五年级计算机课评课,小学数学五年级下册公开课《分数的意义》听课心得体会评课稿...
  19. centos7防火墙命令
  20. 阿里云S级新游上云最佳实践

热门文章

  1. ORA-01810: 格式代码出现两次
  2. Eclipse 运行Openfire源码(Windows)
  3. 阿里云容器服务体验: 部署 ShellPays 条码支付整合服务平台 -- (四)结案陈词
  4. 解决方案 | tensorflow安装慢解决方案
  5. Nginx静态资源盗链的效果展示
  6. CompletableFuture异步调用
  7. 单体架构到微服务架构的带来的变化
  8. xml方式实现aop-通知的种类
  9. 从源码深处体验Spring核心技术--基于Xml的IOC容器的初始化
  10. 基于xml的方式配置AOP