转自: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的更多相关文章

  1. SQL Server 分组后取Top N

    SQL Server 分组后取Top N(转) 近日,工作中突遇一需求:将一数据表分组,而后取出每组内按一定规则排列的前N条数据.乍想来,这本是寻常查询,无甚难处.可提笔写来,终究是困住了笔者好一会儿 ...

  2. sql分组排序取top

    写法1: use anypay; select tr.* from (select task_code, max(created_at) as cal from task_log group by t ...

  3. hive分组排序 取top N

    pig可以轻松获取TOP n.书上有例子 hive中比较麻烦,没有直接实现的函数,可以写udf实现.还有个比较简单的实现方法: 用row_number,生成排名序列号.然后外部分组后按这个序列号多虑, ...

  4. SQL语句分组排序,多表关联排序

    SQL语句分组排序,多表关联排序总结几种常见的方法: 案例一: 在查询结果中按人数降序排列,若人数相同,则按课程号升序排列? 分析:单个表内的多个字段排序,一般可以直接用逗号分割实现. select ...

  5. 一条Sql语句分组排序并且限制显示的数据条数

    如果我想得到这样一个结果集:分组排序,并且每组限定记录集的数量,用一条SQL语句能办到吗? 比如说,我想找出学生期末考试中,每科的前3名,并按成绩排序,只用一条SQL语句,该怎么写? 表[TScore ...

  6. mysql 分组排序取最值

    查各个用户下单最早的一条记录 查各个用户下单最早的前两条记录 查各个用户第二次下单的记录 一.建表填数据: SET NAMES utf8mb4; -- 取消外键约束 ; -- ------------ ...

  7. mysql分组排序取最大值所在行,类似hive中row_number() over partition by

    如下图, 计划实现 :按照 parent_code 分组, 取组中code最大值所在的整条记录,如红色部分.(类似hive中: row_number() over(partition by)) sel ...

  8. 记一次有意思的 SQL 实现 → 分组后取每组的第一条记录

    开心一刻 今天,朋友气冲冲的走到我面前 朋友:我不是谈了个女朋友,谈了三个月嘛,昨天我偷看她手机,你猜她给我备注什么 我:备注什么? 朋友:舔狗 2 号! 我一听,气就上来了,说道:走,找她去,这婆娘 ...

  9. SQL获取分组后取某字段最大一条记录(求每个类别中最大的值的列表)

    获取分组后取某字段最大一条记录 方法一:(效率最高) select * from test as a where typeindex = (select max(b.typeindex) from t ...

随机推荐

  1. Swift 模式匹配

    前言 在 Swift 中模式匹配是个重要的概念. 最常用的模式匹配是 switch 语法. 模式匹配非常灵活,在使用 switch 进行一轮模式匹配时,不需要所有的 case 都是同一种风格. let ...

  2. Linux好用的工具命令 - nl/du

    nl 添加行号后打印输出文本内容,以下例子演示了cat 和nl 输出nlDemo文档的区别. [root@ptarmiganantelope:~]# cat nlDemo root:x:0:0:roo ...

  3. MXNET:权重衰减-gluon实现

    构建数据集 # -*- coding: utf-8 -*- from mxnet import init from mxnet import ndarray as nd from mxnet.gluo ...

  4. 施工测量中Cad一些非常有用的插件

    经常会遇到坐标在cad中批量展点.从cad中批量保存坐标点.导入cad中的坐标怎么才能有点号,怎么快速标注cad里的坐标点··· ··· 这一切都是可以程序化的,cad是可以二次开发的,我经常用易语言 ...

  5. 【转】WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等 还是先看看效果图吧:   定义Button按钮名称叫FButton,主要是集成了 ...

  6. Linux报“ '/usr/bin' is not included in the PATH environment variable”解决方法

    https://www.cnblogs.com/alvinwei1024/p/4811993.html https://blog.csdn.net/drbinzhao/article/details/ ...

  7. Spark学习笔记——构建基于Spark的推荐引擎

    推荐模型 推荐模型的种类分为: 1.基于内容的过滤:基于内容的过滤利用物品的内容或是属性信息以及某些相似度定义,来求出与该物品类似的物品. 2.协同过滤:协同过滤是一种借助众包智慧的途径.它利用大量已 ...

  8. shell脚本介绍
 shell脚本结构和执行
date命令用法
 shell脚本中的变量

  9. 解决java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone

    使用spring boot整合MySQL时一直报 java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecog ...

  10. zabbix参考文档

    http://www.zsythink.net/archives/category/%E8%BF%90%E7%BB%B4%E7%9B%B8%E5%85%B3/zabbix/