2019年6月12日更新:MySQL 8已经支持row_number、rank、dense_rank、over函数,完美实现分组排序功能。

# 使用row_number排序,注意排名没有并列
select 学号,课程号,成绩,
row_number()
over(PARTITION by 课程号 ORDER BY 成绩 desc) as 排名
from score ORDER BY 课程号,排名;

# 使用rank排序,注意并列排名没有连续
select 学号,课程号,成绩,
rank()
over(PARTITION by 课程号 ORDER BY 成绩 desc) as 排名
from score ORDER BY 课程号,排名;

# 使用dense_rank排序,注意并列排名是连续的
select 学号,课程号,成绩,
dense_rank()
over(PARTITION by 课程号 ORDER BY 成绩 desc) as 排名
from score ORDER BY 课程号,排名;

主要理解over()开窗函数的用法,感觉它跟group by有点像,不过group by后每个组就只有一行,但是开窗函数相当于分割成多个表,然后对每个表汇总操作,且行数不变。


今天遇到分组top N查询的问题,对于使用关联子查询的解决方法没有理解。暂且记录下来。

select * from score as a
where (select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)<2
order by a.课程号,a.成绩 desc;

各科成绩前两名
select * from score as a
where (select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)<2
order by a.课程号,a.成绩 desc;

各科成绩后两名

另外还有比较原始的方法是,先查出课程号(即有哪些分组),然后对每个分组的成绩排序,使用limit取topN,最后使用union all进行合并。

select 课程号 from score group by 课程号;

查看分组(课程号)
select 学号,课程号,成绩 from score
where 课程号='0001'
order by 成绩 desc
limit 2 

查看这一组的前两名

因此,可以将三门课程的top 2合并起来:

各科成绩的前两名

注意,第二种方法实际上是取前n条记录,对于数值相同的多条记录会漏掉。因此还是建议使用第一种方法。

第一种方法没有理解,待续……

——————————————————————————————————————

2019年5月25日,下午想明白了使用关联子查询解决分组TopN的问题。

示例表
-- 求最大Top2
select * from score1 as a
where(
SELECT count(*) from score1 as b where a.课程号=b.课程号 and a.成绩 < b.成绩
)<2;

主要难以理解的是:(select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)<2。实际上这一句可以分解为两句:

(select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)=1 or
(select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)=0

抑或是:

(select count(b.成绩) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)=1 or
(select count(b.成绩) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)=0

然后重点理解这个条件:a.成绩<b.成绩。假设a.成绩的值是60/70/80/90,当然b.成绩的值也是60/70/80/90,我们可以看做a.成绩的每一行,依次与b.成绩去配对:

1)60(a.成绩)与60/70/80/90(b.成绩)配对,在a.成绩<b.成绩这一条件下,count(b.成绩)=3,即b.成绩取70/80/90才满足条件;

2)70(a.成绩)与60/70/80/90(b.成绩)配对,在a.成绩<b.成绩这一条件下,count(b.成绩)=2,即b.成绩取80/90才满足条件;;

3)80(a.成绩)与60/70/80/90(b.成绩)配对,在a.成绩<b.成绩这一条件下,count(b.成绩)=1,即b.成绩取90才满足条件;;

4)90(a.成绩)与60/70/80/90(b.成绩)配对,在a.成绩<b.成绩这一条件下,count(b.成绩)=0,即b.成绩中任意一个值都不满足条件。

因此,这个条件:select count(*) from score as b where a.课程号=b.课程号 and a.成绩<b.成绩)<2 实际上得到了a.成绩=80/90,也就是最大Top2。

同理,这个条件:select count(*) from score as b where a.课程号=b.课程号 and a.成绩>b.成绩)<2 实际上得到了a.成绩=60/70,也就是最小Top2。

____________________________________________________________________________________________

扩展:

/*有些國家的人口是同洲份的所有其他國的3倍或以上。列出 國家名字name 和 洲份 continent。*/
select a.name,a.continent
from world as a
where
-- a.表的第一人数除以3,与同组的相同的b表人数比较,大于或等于
(
select count(*) from world as b
where a.continent=b.continent and a.population/3>=b.population
)=
-- 得到的行数是:同一分组的行数减去一
(select count(*) from world as c where a.continent=c.continent)-1

分组 查出id最大的_MySQL分组top N问题疑点相关推荐

  1. mysql 分组查出来横向展示_Mysql探索(一):B+Tree索引

    MySQL是目前业界最为流行的关系型数据库之一,而索引的优化也是数据库性能优化的关键之一.所以,充分地了解MySQL索引有助于提升开发人员对MySQL数据库的使用优化能力.  MySQL的索引有很多种 ...

  2. mysql 分组查出来横向展示_MySQL汇总分析(group by)

    制作表格的代码在这里找哦! https://zhuanlan.zhihu.com/p/162696033​zhuanlan.zhihu.com stu表:学生学号.学生姓名.学生年龄.学生性别 sc表 ...

  3. mysql分组取日期最大的记录_mysql 分组 group by, 排序 取每条记录中,时间最大

    mysql教程 分组 group by, 排序 取每条记录中,时间最大的一条记录 select a.* from test a, (select aid, max(day) max_day from ...

  4. mysql先过滤后分组_MySQL分组过滤

    使用HAVING字句对分组结果进行过滤. 示例 有一个表格socre_sheet: mysql> SELECT * FROM score_sheet; +----+--------+------ ...

  5. mysql余额统计_实现按部门月卡余额总额分组统计的SQL查_mysql

    陈优章的专栏 (原创,到现在为至最为复杂的SQL查询代码)实现按部门月卡余额总额分组统计的SQL查询代码(在Ms SQL Server中调试通过) SELECT dp.dpname1 AS 部门, c ...

  6. mysql 分类查询_MySQL:分组查询

    #进阶5:分组查询 /*语法:select 分组函数,列(要求出现在group by的后面)from 表[where 筛选条件]group by 分组的列表[order by 子句]注意:查询列表必须 ...

  7. mysql 数组 分组_mysql分组查询数组

    mysql分组查询数组 - 技术改变生活 - 开源中国社区 首页 开源项目 Java 开源软件 C# 开源软件 PHP 开源软件 C/C++ 开源软件 Ruby 开源软件 Python 开源软件 Go ...

  8. python数据科学包第三天(索引、分组计算、数据聚合、分组运算和转换、载入数据、日期范围、数据可视化)

    索引 行索引 列索引 索引的分类 重复索引的处理 s = pd.Series(np.random.rand(5), index=list('abcde')) s a 0.566924 b 0.6034 ...

  9. R语言使用ggplot2包的快速可视化函数qplot绘制分组箱图(jitter、分组颜色配置)实战

    R语言使用ggplot2包的快速可视化函数qplot绘制分组箱图(jitter.分组颜色配置)实战 目录 R语言使用ggplot2包的快速可视化函数qplot绘制分组箱图(jitter.分组颜色配置) ...

最新文章

  1. 极大似然估计_干货|一文理解极大似然估计
  2. 国庆广州(羊城)之旅
  3. Redhat 5 配置DHCP服务器
  4. smartforms金额或者数量字段显示不出来
  5. hdu 3172(并查集+hash)
  6. python 解析 配置文件
  7. hive 时间转字符串_2. HIVE 基本操作
  8. veket智能机器人
  9. 工作209:整理订单的重置逻辑
  10. rgss加密文件解包器_Unity AssetBundle高效加密案例分享
  11. 紫书 习题8-14 UVa 1616(二分+小数化分数+精度)
  12. mysql临键锁_详解 MySql InnoDB 中的三种行锁(记录锁、间隙锁与临键锁)
  13. Laravel 5.4 首次搭建,从 clone 到运行成功
  14. Html5用户注册页面
  15. 技嘉服务器主板装系统,技嘉主板bios设置图解教程
  16. 吐血整理!跳槽字节跳动涨薪
  17. appium示例代码python_Appium+python测试app实例
  18. 绘图软件推荐——Diagram Designer
  19. lara with tp
  20. 接口显示返回值正常,但是拿到的值却是undefined?

热门文章

  1. Python使用逻辑回归算法根据三围数据判断用户性别
  2. 数据包络分析方法与maxdea软件_SEM常用的4种数据分析方法,让你的优化工作事半功倍!...
  3. c++如何打印一维数组首地址_4.1 数组的定义
  4. windows版一键绕id工具_【实用工具】一键关闭/开启Windows防火墙、禁止更新系统...
  5. leetcode_150. 逆波兰表达式求值
  6. python类的魔法方法基础
  7. c语言整型的最大范围,整型变量范围最大到32750?
  8. 力扣669. 修剪二叉搜索树(JavaScript)
  9. java内部类为什么使用很少_Java内部类你真的会吗?
  10. 计算机网络概述的功能 组成,计算机网络的概述