SQL之分组排序取top n
转自:http://blog.csdn.net/wguangliang/article/details/50167283
要求:按照课程分组,查找每个课程最高的两个成绩。
数据文件如下:
第一列no为学号,第二列course为课程,第三列score为分数
[plain] view plain copy
1. mysql> select * from lesson;
2. +-------+---------+-------+
3. | no | course | score |
4. +-------+---------+-------+
5. | N0101 | Marth | 100 |
6. | N0102 | English | 12 |
7. | N0102 | Chinese | 55 |
8. | N0102 | History | 58 |
9. | N0102 | Marth | 25 |
10. | N0103 | English | 100 |
11. | N0103 | Chinese | 87 |
12. | N0103 | History | 88 |
13. | N0103 | Marth | 72 |
14. | N0104 | English | 20 |
15. | N0104 | Chinese | 60 |
16. | N0104 | History | 88 |
17. | N0104 | Marth | 56 |
18. | N0105 | English | 56 |
19. | N0105 | Chinese | 88 |
20. | N0105 | History | 88 |
21. | N0201 | English | 66 |
22. | N0201 | Chinese | 77 |
23. | N0201 | History | 80 |
24. | N0201 | Marth | 100 |
25. | N0202 | English | 35 |
26. | N0202 | Chinese | 56 |
27. | N0202 | History | 86 |
28. | N0202 | Marth | 99 |
29. | N0203 | English | 100 |
30. | N0203 | Chinese | 87 |
31. | N0203 | History | 88 |
32. | N0203 | Marth | 57 |
33. | N0204 | English | 98 |
34. | N0204 | Chinese | 100 |
35. | N0204 | History | 66 |
36. | N0204 | Marth | 71 |
37. | N0205 | English | 98 |
38. | N0205 | Chinese | 100 |
39. | N0205 | History | 66 |
40. | N0205 | Marth | 71 |
41. | N0301 | English | 66 |
42. | N0301 | Chinese | 89 |
43. | N0301 | History | 68 |
44. | N0301 | Marth | 83 |
45. | N0302 | English | 76 |
46. | N0302 | Chinese | 99 |
47. | N0302 | History | 80 |
48. | N0302 | Marth | 74 |
49. | N0303 | English | 100 |
50. | N0303 | Chinese | 100 |
51. | N0303 | History | 88 |
52. | N0303 | Marth | 57 |
53. | N0304 | English | 76 |
54. | N0304 | Chinese | 100 |
55. | N0304 | History | 66 |
56. | N0304 | Marth | 86 |
57. | N0305 | English | 98 |
58. | N0305 | Chinese | 100 |
59. | N0305 | History | 40 |
60. | N0305 | Marth | 59 |
61. | N0306 | English | 52 |
62. | N0306 | Chinese | 87 |
63. | N0306 | History | 72 |
64. | N0306 | Marth | 71 |
65. | N0101 | Chinese | 55 |
66. | N0101 | History | 84 |
67. | N0101 | English | 82 |
68. | N0101 | English | 82 |
69. +-------+---------+-------+
70. 64 rows in set
在hive上查询
1. select a.course,a.score
2. from
3. (
4. select course,score,row_number() over(partition by course order by score desc) as n
5. from lesson
6. )a
7. where a.n<=2;
其中:
1. row_number() over(partition by course order by score desc)
意思是以课程分组,按成绩递减排序,并为每组中的数据打上行号的标记,从1开始。
这样,再在外层套一层过滤行号小于等于2的即可:-D
查询结果如下图1所示:

图1 Hive查询结果
在mysql上查询
由于MySQL不支持row_number()over()等窗口函数
方法1.自查询比较
1. select course,score
2. from lesson a
3. where 2 >
4. (
5. select count(1)
6. from lesson b
7. where a.score<b.score and a.course=b.course
8. )
9. 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
1. SET @row=0;
2. SET @groupid='';
3. select a.course,a.score
4. from
5. (
6. select no,course,score,case when @groupid=course then @row:=@row+1 else @row:=1 end rownum,@groupid:=course from lesson
7. order by course,score desc
8. )a
9. where a.rownum<=2;
其中:
@row用于统计行号,@groupid用于分组,记录该组的名称
1. select no,course,score,case when @groupid=course then @row:=@row+1 else @row:=1 end rownum,@groupid:=course from lesson
2. order by course,score desc
意思是:按照分组名course和需要的排序score递增 进行排序,这样,相同课程就会排在一起,且相同的课程之间按照成绩排序。
取出一条数据,如果该条数据的course与@group相同,则意味着是相同课程之间的比较,那么@row自加1。
否则意味着该条数据是另一门课程的第一条数据,则@row=1
这样每个课程就能够按照成绩排序并标记上行号
那么外层只需要过滤rownum<=2即可得到每门课的前2个最高分。
最后执行结果与hive一致,不再上图片了。
SQL之分组排序取top n的更多相关文章
- SQL Server 分组后取Top N
SQL Server 分组后取Top N(转) 近日,工作中突遇一需求:将一数据表分组,而后取出每组内按一定规则排列的前N条数据.乍想来,这本是寻常查询,无甚难处.可提笔写来,终究是困住了笔者好一会儿 ...
- sql分组排序取top
写法1: use anypay; select tr.* from (select task_code, max(created_at) as cal from task_log group by t ...
- hive分组排序 取top N
pig可以轻松获取TOP n.书上有例子 hive中比较麻烦,没有直接实现的函数,可以写udf实现.还有个比较简单的实现方法: 用row_number,生成排名序列号.然后外部分组后按这个序列号多虑, ...
- SQL语句分组排序,多表关联排序
SQL语句分组排序,多表关联排序总结几种常见的方法: 案例一: 在查询结果中按人数降序排列,若人数相同,则按课程号升序排列? 分析:单个表内的多个字段排序,一般可以直接用逗号分割实现. select ...
- 一条Sql语句分组排序并且限制显示的数据条数
如果我想得到这样一个结果集:分组排序,并且每组限定记录集的数量,用一条SQL语句能办到吗? 比如说,我想找出学生期末考试中,每科的前3名,并按成绩排序,只用一条SQL语句,该怎么写? 表[TScore ...
- mysql 分组排序取最值
查各个用户下单最早的一条记录 查各个用户下单最早的前两条记录 查各个用户第二次下单的记录 一.建表填数据: SET NAMES utf8mb4; -- 取消外键约束 ; -- ------------ ...
- mysql分组排序取最大值所在行,类似hive中row_number() over partition by
如下图, 计划实现 :按照 parent_code 分组, 取组中code最大值所在的整条记录,如红色部分.(类似hive中: row_number() over(partition by)) sel ...
- 记一次有意思的 SQL 实现 → 分组后取每组的第一条记录
开心一刻 今天,朋友气冲冲的走到我面前 朋友:我不是谈了个女朋友,谈了三个月嘛,昨天我偷看她手机,你猜她给我备注什么 我:备注什么? 朋友:舔狗 2 号! 我一听,气就上来了,说道:走,找她去,这婆娘 ...
- SQL获取分组后取某字段最大一条记录(求每个类别中最大的值的列表)
获取分组后取某字段最大一条记录 方法一:(效率最高) select * from test as a where typeindex = (select max(b.typeindex) from t ...
随机推荐
- 11G新特性 -- archival(long-term)backups
在oracle 10g中,提供了backup ... keep功能来重载配置好的retention策略. 在oracle 11g中,可以重定义backup ... keep命令来创建长期保留的备份,称 ...
- linux 磁盘空间满了,排查记录
先贴命令:du -m --max-depth=1或du -h --max-depth=1du:用于统计linux中文件或目录所占磁盘空间的大小du参数######-m:以M为单位展示查询结果-h:以K ...
- IOS开发 文件路径
1.开发平台路径: /Developer/Platforms 此路径下一般有三个目录,分别是mac电脑.模拟器.iphone真机 MacOSX.platform iPhoneSimulator.pla ...
- 从NSTimer的失效性谈起(二):关于GCD Timer和libdispatch
一.GCD Timer的创建和安放 尽管GCD Timer并不依赖于NSRunLoop,可是有没有可能在某种情况下,GCD Timer也失效了?就好比一開始我们也不知道NSTimer相应着一个runl ...
- lua -- mysql导出json
到处的json文件放到这个目录下 E:\xg\client\cocos2d-x-2.2.2\projects\tool\propjson
- ECMAScript 6 入门之字符串
1.新增字符串的方法 1.字符是否存在 console.log("Yo".indexOf("Y")!=-1); console.log("Yo&quo ...
- 15款基于 jQuery模态对话框
在数字世界的竞争已大大增加.这就是为什么要确保网络设计的各个方面都是一流的,这是很重要的.从布局到一些非常小的东西,比如对话框,每一件都需要设计得很好.对话框通常被忽视,但它们可能对访问者有很大的影响 ...
- centos 6.4 使用epel 源
EPEL是RHEL 的 Fedora 软件仓库,把它添上,你就可以获得 RHEL AS 的高质量.高性能.高可靠性,又需要方便易用(关键是免费)的软件包更新功能.EPEL(Extra Packages ...
- VirtualBox 4.3“不能为虚拟电脑 打开一个新任务”解决方案 - 转
最近做项目因为设计不同网络,还要大家文件和数据库服务器环境,所以需要多台机器进行测试,最简单的方法当然是跑多个虚拟机了.虽然不可否认 VMware 确实强大,不过相比较起来我更喜欢功能比较简单轻省的 ...
- [Bayes] prod: M-H: Independence Sampler for Posterior Sampling
M-H是Metropolis抽样方法的扩展,扩展后可以支持不对称的提议分布. 对于M-H而言,根据候选分布g的不同选择,衍生出了集中不同的变种: (1)Metropolis抽样方法 (2)随机游动Me ...