MySQL分类排名和分组TOP N实例详解
作者:奔放的程序猿 发布时间:2024-01-24 11:23:16
标签:MySQL,分类,分组
表结构
学生表如下:
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条不重复的
来源:https://blog.csdn.net/Dlgdlgd/article/details/122129327
0
投稿
猜你喜欢
- 本文实例讲述了Python基于正则表达式实现文件内容替换的方法。分享给大家供大家参考,具体如下:最近因为有一个项目需要从普通的服务器移植到S
- 本文为大家分享了Python多线程聊天室,是一个Socket,两个线程,一个是服务器,一个是客户端。 最近公司培训,要写个大富翁的小程序,准
- Part.I 预备知识Chap.I 几个概念的区分Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了
- 一般跟踪训练的ground_truth的数据保存在文本文文件中,故每一行的数据为一张图片的标签数据,这个时候读取每一张图片的标签,具体实现如
- Python 中的 timeit 模块可以用来测试一段代码的执行耗时,如一个变量赋值语句的执行时间,一个函数的运行时间等。timeit 模块
- 在制作网页以及编程的时候,适当的进行注释,不仅使自己的思路清晰,极大地减轻了维护的难度,而且方便项目组其他人了解你的代码,方便对代码的理解以
- 将Django与MongoDB集成在不更改Django ORM的情况下,将MongoDB用作Django项目的后端数据库。使用Django
- 为数据库配置比较大的内存,可以有效提高数据库性能。因为数据库在运行过程中,会在内存中划出一块区域来作为数据缓存。通常情况下,用户访问数据库时
- 如何在读取Excel文件时创建列表的下拉菜单?代码如下,用来创建工作表列表的下拉菜单: < select 
- 发现一个有意思的现象,labelimg打开图片和xml标签时候,看不到标注好的框框,仔细查看了xml文件,没发现什么异常,后面试一下,才发现
- 本文主要研究的是selenium python浏览器多窗口处理的相关内容,分享了操作实例代码,具体如下:#!/usr/bin/python#
- 用面向对象的思维解决问题的重点当遇到一个需求的时候不用自己去实现,如果自己一步步实现那就是面向过程;应该找一个专门做这个事的人来做。面向对象
- #!/bin/perlprint "please input some lines,then press Ctrl+Z. \n&q
- 1、Introduction之前写过2篇文章,分别是:Mysql主从同步的原理 Myql主从同步实战 基于此,我们再实
- pyfinance简介在查找如何使用Python实现滚动回归时,发现一个很有用的量化金融包——pyfinance。顾名思义,pyfinanc
- 大家已经从实际使用中了解了jquery这个javascript框架的强大,其实jquery更加强大的是可扩展。你可以编写自己的基于jquer
- 一个ASP文件通常包含HTML标签,有时和一个HTML文件非常类似。然而,ASP文件(除了包含HTML标签外),还可以包括服务器的脚本程序,
- 问题背景:这个问题是在爬取某夕夕商城遇到的问题,原本的方案是用selenium + chromedriver + mitmproxy开心的刷
- 本文研究的主要是python删除过期log文件的相关内容,具体介绍如下。1. 用Python遍历目录os.walk方法可以很方便的得到目录下
- 反射在Python中,能够通过一个对象,找出type、class、attribute或者method的能力,成为反射。函数与方法内建函数:g