数据库查询*分组排序取top n

要求:按照课程分组,查找每个课程最高的两个成绩。

数据文件如下:

第一列no为学号,第二列course为课程,第三列score为分数

mysql> select * from lesson;
+-------+---------+-------+
| no    | course  | score |
+-------+---------+-------+
| N0101 | Marth   |   100 |
| N0102 | English |    12 |
| N0102 | Chinese |    55 |
| N0102 | History |    58 |
| N0102 | Marth   |    25 |
| N0103 | English |   100 |
| N0103 | Chinese |    87 |
| N0103 | History |    88 |
| N0103 | Marth   |    72 |
| N0104 | English |    20 |
| N0104 | Chinese |    60 |
| N0104 | History |    88 |
| N0104 | Marth   |    56 |
| N0105 | English |    56 |
| N0105 | Chinese |    88 |
| N0105 | History |    88 |
| N0201 | English |    66 |
| N0201 | Chinese |    77 |
| N0201 | History |    80 |
| N0201 | Marth   |   100 |
| N0202 | English |    35 |
| N0202 | Chinese |    56 |
| N0202 | History |    86 |
| N0202 | Marth   |    99 |
| N0203 | English |   100 |
| N0203 | Chinese |    87 |
| N0203 | History |    88 |
| N0203 | Marth   |    57 |
| N0204 | English |    98 |
| N0204 | Chinese |   100 |
| N0204 | History |    66 |
| N0204 | Marth   |    71 |
| N0205 | English |    98 |
| N0205 | Chinese |   100 |
| N0205 | History |    66 |
| N0205 | Marth   |    71 |
| N0301 | English |    66 |
| N0301 | Chinese |    89 |
| N0301 | History |    68 |
| N0301 | Marth   |    83 |
| N0302 | English |    76 |
| N0302 | Chinese |    99 |
| N0302 | History |    80 |
| N0302 | Marth   |    74 |
| N0303 | English |   100 |
| N0303 | Chinese |   100 |
| N0303 | History |    88 |
| N0303 | Marth   |    57 |
| N0304 | English |    76 |
| N0304 | Chinese |   100 |
| N0304 | History |    66 |
| N0304 | Marth   |    86 |
| N0305 | English |    98 |
| N0305 | Chinese |   100 |
| N0305 | History |    40 |
| N0305 | Marth   |    59 |
| N0306 | English |    52 |
| N0306 | Chinese |    87 |
| N0306 | History |    72 |
| N0306 | Marth   |    71 |
| N0101 | Chinese |    55 |
| N0101 | History |    84 |
| N0101 | English |    82 |
| N0101 | English |    82 |
+-------+---------+-------+
64 rows in set

在hive上查询

select a.course,a.score
from
(
select course,score,row_number() over(partition by course order by score desc) as n
from lesson
)a
where a.n<=2; 

其中:

row_number() over(partition by course order by score desc)

意思是以课程分组,按成绩递减排序,并为每组中的数据打上行号的标记,从1开始。

这样,再在外层套一层过滤行号小于等于2的即可:-D

查询结果如下图1所示:

图1 hive查询结果

在mysql上查询

由于mysql不支持row_number()over()等窗口函数

所以/(ㄒoㄒ)/~~

方法1.自查询比较

select course,score
from lesson a
where 2 >
(
select count(1)
from lesson b
where a.score<b.score and a.course=b.course
)
order by a.course,a.score desc;

因为是查询最高的两个成绩,所以是2>,如果查询最高的前N个成绩,改成 N>

该条sql语句的大概思路是:

从a表中拿出一条数据,与b表中所有与该条数据相同course的数据比较,统计出b表有多少相同课程的score比该条数据的score高;

如果b表中有0条比该条数据高,则该条数据是该门课程的最高分;

如果统计出有1条数据,则该条数据是该门课程分数的第二高;

但是,还存在一些问题:

比如,最高分存在多个,则会统计出多于2条的数据,如下图2统计结果也有所反应:

图2 mysql查询结果

方法2.动态sql

SET @row=0;
SET @groupid='';
select a.course,a.score
from
(
select no,course,score,case when @groupid=course then @row:=@row+1 else @row:=1 end rownum,@groupid:=course from lesson
order by course,score desc
)a
where a.rownum<=2;

其中:

@row用于统计行号,@groupid用于分组,记录该组的名称
select no,course,score,case when @groupid=course then @row:=@row+1 else @row:=1 end rownum,@groupid:=course from lesson
order by course,score desc
意思是:按照分组名course和需要的排序score递增 进行排序,这样,相同课程就会排在一起,且相同的课程之间按照成绩排序。
取出一条数据,如果该条数据的course与@group相同,则意味着是相同课程之间的比较,那么@row自加1。
否则意味着该条数据是另一门课程的第一条数据,则@row=1
这样每个课程就能够按照成绩排序并标记上行号
那么外层只需要过滤rownum<=2即可得到每门课的前2个最高分。
最后执行结果与hive一致,不再上图片了。

sql分组排序取top n相关推荐

  1. SQL:分组排序取top N

    1 法一 在hive上查询 select a.course,a.score from( select course,score,row_number() over(partition by cours ...

  2. mysql 分组排序取前n_mysql分组排序取前N条记录的最简洁的单条sql ! | 学步园

    -- mysql分组排序取前N条记录的最简洁的单条sql. use test; drop table if exists test; create table test ( id int primar ...

  3. SQL 分组排序后取值

    SQL 分组排序后取值 场景前要: 从前有三个班级,每个班级的学生成绩各异,有一天睿智的校长希望知道这一年中,每个班级近一年里所有的学生成绩信息,和查询每个班级近一年里所有第一名的学生成绩信息,故事由 ...

  4. HQL语句使用row_number() over(partition by),分组排序取topN

    在 mysql中实现over partiton by,进行分组排序取topN https://georgedage.blog.csdn.net/article/details/103557651 使用 ...

  5. mysql分组排序取第一条记录

    方式1:内层使用DISTINCT SELECTtype,senderName,subTitle FROM(SELECT DISTINCTTYPE AS type,SENDER_USERNAME AS ...

  6. mysql 分组排序 取前top n

    力扣mysql 题目为: Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId . +----+-------+ ...

  7. mysql中实现over partiton by,进行分组排序取topN

    创表 CREATE TABLE `t1` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`class` ...

  8. oracle和mysql分组排序取第一条数据

    场景 需求 查每个人的Orderstr 是1 的数据,并保证name不重复 oracle select *   from (SELECT a.*, row_number() over(partitio ...

  9. LeetCode-185 : sql分组排序再取前几位

    题目描述:在EMPLOYEE表中查询每个部门工资前三高的员工. 题目分析: 题目中还是已经描述的比较清楚,比如某个部门工资按从高到低排序为9000,8900,8900,8500,8000-那么该部门需 ...

  10. hive sql 分组随机取数

    问题描述(举例): 表结构(students_article): student_id, article id_1,article_1 id_1,article_2 id_1,article_3 id ...

最新文章

  1. oauth2 单点登录_Spring Security Oauth2和Spring Boot实现单点登录
  2. js 删除对象某个属性_JS里的数据类型
  3. rⅰd的意思_计量经济学练习题
  4. 知识图谱(四)——实体识别和扩展
  5. 按位异或运算和求反运算解析
  6. rabbitmq 连接过程详解
  7. 数据库开发——MySQL——单表查询
  8. 使用RxJava帮助低功耗蓝牙(BLE)进行通信
  9. java map取第一个元素_Java Set接口 Map 与枚举
  10. 大学计算机需要论文吗,关于大学计算机论文范文.docx
  11. vc服务器的作用,总结虚拟化服务器的好处
  12. 8款网页瀑布流布局插件(很不错的效果)
  13. 2.1HTML网页之table标签B
  14. cas112-27-6|三乙二醇/二缩三乙二醇/三甘醇|三乙二醇 透明液体
  15. [高数][高昆轮][高等数学上][第一章-函数与极限]10.闭区间上连续函数的性质
  16. Zabbix-Sender 增加自定义监控项-- Ping 到目的地链路监控--bat脚本循环运行
  17. 众人给诺基亚支招 Android提议何时了?
  18. Java单体应用 - 架构模式 - 03.设计模式-10.装饰器模式
  19. 程序员基础能力系列(1)——vim快捷键总结
  20. 仿肯德基宅急送App-Vue实战

热门文章

  1. 云计算10个入门基础知识
  2. 计算机考研专业课靠什么意思,计算机考研专业课831什么意思???
  3. 【论文阅读】A Memory-Efficient Deterministic Finite Automaton-Based Bit-Split String Matching Scheme
  4. java线程倒计时_Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger...
  5. 1.7-工控上位机软件开发平台介绍
  6. 文献阅读1:Deep Learning for Image Super-resolution: A Survey
  7. u盘坏了在计算机不显示,U盘在电脑上不能显示怎么办
  8. MySQL修改数据表中的字段名_MySQL修改数据表中的字段名
  9. 网易涉暴力裁员引众怒 5大争议背后是否违法?
  10. 本机ip与外网ip(附带查询方法)