使用mysql、hive查询各科成绩前三名

一、建表造数据

建表:

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

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

order by s1.subject,s1.score desc;

查询语句重点在于 -->子查询语句: select count(1) from scores s2 where s1.subject=s2.subject and s1.score

意思是:统计学生个数,即关联两个分数表s1、s2,外层查询每查询一次,再到内层循环中查询表s2,当课程名相同时,统计 s1.score

这么说可能还是有点懵,现在我们来走一遍流程,从头到尾依次遍历一次,详细说明:

首先从学生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

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

三、使用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;

查询结果如下:

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

  1. 查询前几条记录SQL在不同数据库中的用法

    13,(1)查询前几条记录SQL在不同数据库中的用法; 1. ORACLE SELECT * FROM TABLE1 WHERE ROWNUM<=N 2. INFORMIX SELECT FIR ...

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

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

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

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

  4. MySQL 百万级/千万级表 总记录数查询

    业务背景:基于 InnoDB 存储引擎的表,在数据量达到百万级之后,用 count 函数查询表记录总数会变得很慢,会导致服务请求超时.针对这种情况总结下我所想到的解决办法. 实际业务场景: 表名 表名 ...

  5. mysql查询sql中日期为当天的记录_SQL 查询当天,本月,本周的记录 sql 查询日期...

    SELECT * FROM 表 WHERE CONVERT(Nvarchar, dateandtime, 111) = CONVERT(Nvarchar, GETDATE(), 111)   ORDE ...

  6. MYSQL避免全表扫描__如何查看sql查询是否用到索引(mysql)

    MYSQL避免全表扫描 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引 2.应尽量避免在 where 子句中对字段进行 null 值判断,否 ...

  7. php查询MySQL结果转化为数组_PHP如何将SQL查询结果转为多维数组,并按查询行输出...

    在php中,SQL查询数据库得到的是多行多列的数据,如何将查询结果转为二维数组,我的目的是把多行查询结果按行输出,有没有什么方法,求详细代码示例查询结果示例:reserv_idnametyper... ...

  8. sql server整表查询慢_这里有一个慢 SQL 查询等你来优化

    背景 最近工作上遇到一个"神奇"的问题, 或许对大家有帮助, 因此形成本文. 问题大概是, 我有两个表 TableA, TableB, 其中 TableA 表大概百万行级别(存量业 ...

  9. oracle未授权sql查询,【oracle使用笔记3】sql查询遇到的若干问题总结

    在整个开发过程当中,sql查询操做的频率比较高,在不一样的业务场景下会出现不一样的查询需求,如下是我在项目中遇到的查询需求,总结一下.sql [查询一]:取查询出的第一条数据oracle select ...

最新文章

  1. 文本框换行_多行文本框的认识以及代码详解
  2. 【Python基础】科学计算库Scipy简易入门
  3. 90 % 的 Python 开发者不知道的描述符应用
  4. .NET Core 3.0稳定版发布
  5. mysql5.7 主从复制的正常切换【转】
  6. 人脸检测-MTCNN算法笔记和代码解读
  7. 简单易学!一步步带你理解机器学习算法——马尔可夫链蒙特卡罗(MCMC)
  8. C语言爱心动态生日快乐代码
  9. MySQL 数据库管理之 --- SQL 语言进阶二
  10. 异步社区两周年 - 技术图书免费送(活动已结束)
  11. 2015QS世界大学排名-[转]
  12. tp6 防止XSS攻击之表单提交安全校验
  13. /usr/bin/ld: /tmp/ccIHWHTn.o: in function `Cdisk::Cdisk()‘:编译报错解决方案
  14. Cmder | 一款命令行增强工具
  15. 关于飞塔防火墙做端口聚合的时候应该如何选择端口可以达到最好效果。
  16. suse linux 11 xdm图形化,suse xdm 设置
  17. 微信小程序 动态添加类名
  18. Remix使用教程,新版 remix 使用教程
  19. Machine Learning学习笔记(四)EML极限学习机
  20. 【ManageEngine卓豪】局域网监控的作用

热门文章

  1. L1-039 古风排版 (20 分)java
  2. pyinstall ImportError: No module named _bootlocale
  3. 新手怎么学习网站制作?
  4. js动态获取当前时间前后的2年时间
  5. 五年级上册ppt计算机教案,小学五年级信息技术上册教案-
  6. Django笔记十九之manager用法介绍
  7. 苹果屏幕上的小圆点_iPhone点2下屏幕就能截屏,你还在用按键截屏?不会花30秒学...
  8. ios分屏_iPadOS分屏功能快速上手教学,让iPad生产力猛增,不再是泡面盖
  9. 半监督kmeans聚类
  10. React脚手架及CRA脚手架的使用