我的编程空间,编程开发者的网络收藏夹
学习永远不晚

MySQL分类排名和分组TOPN实例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

MySQL分类排名和分组TOPN实例详解

表结构

学生表如下:

CREATE TABLE `t_student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `t_id` int DEFAULT NULL COMMENT '学科id',
  `score` int DEFAULT NULL COMMENT '分数',
  PRIMARY KEY (`id`)
);

数据如下: 

题目一:获取每个科目下前五成绩排名(允许并列)

允许并列情况可能存在如4、5名成绩并列情况,会导致取前4名得出5条数据,取前5名也是5条数据。

SELECT
	s1.* 
FROM
	student s1
	LEFT JOIN student s2 ON s1.t_id = s2.t_id 
	AND s1.score < s2.score 
GROUP BY
	s1.id
HAVING
	COUNT( s2.id ) < 5 
ORDER BY
	s1.t_id,
	s1.score DESC

  ps:取前4名时

 分析:

1.自身左外连接,得到所有的左边值小于右边值的集合。以t_id=1时举例,24有5个成绩大于他的(74、64、54、44、34),是第6名,34只有4个成绩大于他的,是第5名......74没有大于他的,是第一名。

SELECT
	* 
FROM
	student s1
	LEFT JOIN student s2 ON s1.t_id = s2.t_id 
	AND s1.score < s2.score 

  2. 把总结的规律转换成SQL表示出来,就是group by 每个student 的 id(s1.id),Having统计这个id下面有多少个比他大的值(s2.id)

SELECT
	s1.* 
FROM
	student s1
	LEFT JOIN student s2 ON s1.t_id = s2.t_id 
	AND s1.score < s2.score 
GROUP BY
	s1.id
HAVING
	COUNT( s2.id ) < 5 

 3. 最后根据 t_id 分类,score 倒序排序即可。

题目二:获取每个科目下最后两名学生的成绩平均值

取最后两名成绩

SELECT
	s1.* 
FROM
	student s1
	LEFT JOIN student s2 ON s1.t_id = s2.t_id 
	AND s1.score > s2.score 
GROUP BY
	s1.id 
HAVING
	COUNT( s1.id )< 2 
ORDER BY
	s1.t_id,
	s1.score

并列存在情况下可能导致筛选出的同一t_id 下结果条数大于2条,但题目要求是取最后两名的平均值,多条平均后还是本身,故不必再对其处理,可以满足题目要求。 

 分组求平均值:

SELECT
	t_id,AVG(score)
FROM
	(
	SELECT
		s1.*
	FROM
		student s1
		LEFT JOIN student s2 ON s1.t_id = s2.t_id 
		AND s1.score > s2.score
	GROUP BY
		s1.id 
	HAVING
		COUNT( s1.id )< 2 
	ORDER BY
		s1.t_id,
		s1.score 
	) tt 
GROUP BY
	t_id

结果: 

分析:

1. 查询出所有t1.score>t2.score 的记录

SELECT
		s1.*,s2.*
	FROM
		student s1
		LEFT JOIN student s2 ON s1.t_id = s2.t_id 
		AND s1.score > s2.score

2. group by s.id 去重,having 计数取2条

3. group by t_id 分别取各自学科的然后avg取均值

题目三:获取每个科目下前五成绩排名(不允许并列)

SELECT
	* 
FROM
	(
	SELECT
		s1.*,
		@rownum := @rownum + 1 AS num_tmp,
		@incrnum :=
	CASE
			
			WHEN @rowtotal = s1.score THEN
			@incrnum 
			WHEN @rowtotal := s1.score THEN
			@rownum 
		END AS rownum 
	FROM
		student s1
		LEFT JOIN student s2 ON s1.t_id = s2.t_id 
		AND s1.score > s2.score,
		( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it 
	GROUP BY
		s1.id 
	ORDER BY
		s1.t_id,
		s1.score DESC 
	) tt 
GROUP BY
	t_id,
	score,
	rownum 
HAVING
	COUNT( rownum )< 5

 分析:

1.引入辅助参数

SELECT
	s1.*,
	@rownum := @rownum + 1 AS num_tmp,
	@incrnum :=
CASE
		
		WHEN @rowtotal = s1.score THEN
		@incrnum 
		WHEN @rowtotal := s1.score THEN
		@rownum 
	END AS rownum 
FROM
	student s1
	LEFT JOIN student s2 ON s1.t_id = s2.t_id 
	AND s1.score > s2.score,
	( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it

2.去除重复s1.id,分组排序

SELECT
		s1.*,
		@rownum := @rownum + 1 AS num_tmp,
		@incrnum :=
	CASE
			
			WHEN @rowtotal = s1.score THEN
			@incrnum 
			WHEN @rowtotal := s1.score THEN
			@rownum 
		END AS rownum 
	FROM
		student s1
		LEFT JOIN student s2 ON s1.t_id = s2.t_id 
		AND s1.score > s2.score,
		( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it 
	GROUP BY
		s1.id 
	ORDER BY
		s1.t_id,
		s1.score DESC 

 3.GROUP BY    t_id, score, rownum   然后 HAVING 取前5条不重复的

总结

到此这篇关于MySQL分类排名和分组TOP N实例详解的文章就介绍到这了,更多相关MySQL分类排名 TOP N内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

MySQL分类排名和分组TOPN实例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

MySQL中分类排名和分组TOP N的示例分析

这篇文章主要介绍MySQL中分类排名和分组TOP N的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!表结构学生表如下:CREATE TABLE `t_student` ( `id` int NOT NULL
2023-06-26

Mysql索引分类及其使用实例详解

目录mysql的索引分类单列索引创建单列索引的几种方式:唯一索引创建唯一索引的几种方式:联合索引(复合索引)创建联合索引(复合索引)的方式:Mysql的索引类型INDEX | NORMAL 普通索引UNIQUE 唯一索引PRIMARY KE
2022-07-19

Objective-C之Category实现分类示例详解

这篇文章主要为大家介绍了Objective-C之Category实现分类示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

Java模拟rank/over函数实现获取分组排名的方法详解

这篇文章主要为大家详细介绍了Java模拟rank()、over()函数获取分组排名的方法设计及实现,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
2023-05-15

基于Pytorch实现分类器的示例详解

这篇文章主要为大家详细介绍了如何基于Pytorch实现两个分类器: softmax分类器和感知机分类器,文中的示例代码讲解详细,需要的可以参考一下
2023-05-16

git 删除分支和回滚的实例详解

git 删除分支和回滚的实例详解 【git 删除本地分支】git branch -D br【git 删除远程分支】git push origin :br (origin 后面有空格)git代码库回滚: 指的是将代码库某分支退回到以前的某个c
2022-06-04

MYSQL聚合查询、分组查询、联合查询举例详解

目录聚合查询聚合函数count()sum()avg()max()和min()总结分组查询group by 子句having 子句联合查询笛卡尔积内连接外连接自连接子查询单行子查询多行子查询from子句使用子查询合并查询总结 聚合查询聚合查
MYSQL聚合查询、分组查询、联合查询举例详解
2024-09-23

PHP数组用法详解:快速入门与实例分析

PHP 数组是一种非常强大且灵活的数据结构,可以存储多个值并按照索引或键进行访问。在 PHP 中,数组的使用非常普遍,因此掌握数组的用法是非常重要的。本文将从快速入门开始,介绍 PHP 数组的基本概念以及常见操作,并通过实例分析来帮助读者深
PHP数组用法详解:快速入门与实例分析
2024-03-14

MySQL数据库表的模糊/多行/分组/排序/分页查询以及字mysql数据类型的讲解---讲解二

前言:今天给大家讲的是:MySQL数据库表的模糊/多行/分组/排序/分页查询以及mysql数据类型的讲解,当然如果你对数据库的基础操作--对库的创建/对表的增删改查有兴趣,可以去看看我的这篇文章---MySQL数据库表的基础操作(增删改查)---讲解一。5、查
MySQL数据库表的模糊/多行/分组/排序/分页查询以及字mysql数据类型的讲解---讲解二
2018-10-16

SpringBoot多环境配置及配置文件分类实例详解

这篇文章主要介绍了SpringBoot多环境配置及配置文件分类,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-13

编程热搜

目录