MySQL分组,获取组内最新的10条数据

news2024/12/24 21:37:00

一、记录

记录一次SQL,最近在项目中遇到了一个相对比较复杂的SQL。
要求依据分组,获取每个分组后的前10条数据。
分组查询最新的数据,应该都做过,但是获取前10条数据,还是没处理过的。

二、处理

2.1 前期数据准备

新建一个测试表

CREATE TABLE `t_user` (
  `ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `ACCOUNT` varchar(50) DEFAULT NULL COMMENT '账号',
  `NAME` varchar(50) DEFAULT NULL COMMENT '姓名',
  `TIME` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '时间',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='测试表';

搞一批测试数据

INSERT INTO `t_user` (`ACCOUNT`, `NAME`, `TIME`) VALUES 
('zhangsan', '张三', '2024-01-01 00:00:00'),
('zhangsan', '张三', '2024-01-02 00:00:00'),
('zhangsan', '张三', '2024-01-03 00:00:00'),
('zhangsan', '张三', '2024-01-04 00:00:00'),
('zhangsan', '张三', '2024-01-05 00:00:00'),
('zhangsan', '张三', '2024-01-06 00:00:00'),
('zhangsan', '张三', '2024-01-07 00:00:00'),
('zhangsan', '张三', '2024-01-08 00:00:00'),
('zhangsan', '张三', '2024-01-09 00:00:00'),
('zhangsan', '张三', '2024-01-10 00:00:00'),
('zhangsan', '张三', '2024-01-11 00:00:00'),
('lisi', '李四', '2024-01-01 00:00:00'),
('lisi', '李四', '2024-01-02 00:00:00'),
('lisi', '李四', '2024-01-03 00:00:00'),
('lisi', '李四', '2024-01-04 00:00:00'),
('lisi', '李四', '2024-01-05 00:00:00'),
('lisi', '李四', '2024-01-06 00:00:00'),
('lisi', '李四', '2024-01-07 00:00:00'),
('lisi', '李四', '2024-01-08 00:00:00'),
('lisi', '李四', '2024-01-09 00:00:00'),
('lisi', '李四', '2024-01-10 00:00:00'),
('lisi', '李四', '2024-01-11 00:00:00'),
('wangwu', '王五', '2024-01-01 00:00:00'),
('wangwu', '王五', '2024-01-02 00:00:00'),
('wangwu', '王五', '2024-01-03 00:00:00'),
('wangwu', '王五', '2024-01-04 00:00:00'),
('wangwu', '王五', '2024-01-05 00:00:00'),
('wangwu', '王五', '2024-01-06 00:00:00'),
('wangwu', '王五', '2024-01-07 00:00:00'),
('wangwu', '王五', '2024-01-08 00:00:00'),
('wangwu', '王五', '2024-01-09 00:00:00'),
('wangwu', '王五', '2024-01-10 00:00:00'),
('wangwu', '王五', '2024-01-11 00:00:00');

数据如图,进行SQL验证

在这里插入图片描述

2.2 SQL

1、根据账号分组,时间倒叙排序,查询前10条数据

-- 根据账号分组,时间倒叙排序,查询前10条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME ASC 
) t_all
INNER JOIN (
	SELECT max(s_id) s_id, ACCOUNT FROM (
		SELECT (@i:=@i+1) AS s_id, s.* FROM t_user s, (SELECT @i:=0) s_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) s_all ON t_all.ACCOUNT = s_all.ACCOUNT AND t_all.t_id > s_all.s_id - 10
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

得到结果如下,没有出现 1 号的数据,说明SQL可用。
在这里插入图片描述

2.3 延伸

从上面的SQL可以看出来,是以一个基数,然后去截取前10个来做的。
这样的话,我们其实可以变更一下需求,将SQL改写一下。
即:
根据账号分组,时间倒叙排序,查询前10条数据中的,第1条数据。

第一条数据SQL如下:

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第一条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME ASC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 1
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id + 1
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

那么以此类推,第二条数据:

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第二条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME ASC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 2
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id 
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

第三条数据:

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第三条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME ASC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 3
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id - 1
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

第四条数据:

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第四条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME ASC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 4
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME ASC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id - 2
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

三、总结

从上述SQL可以看出:

查询前10条数据,其实就是一个 大于号
而后续的查询前10个数据中的第n条数据,也就是在原先的 大于号 的基础上,进行范围的缩小,增加一个 小于号 ,即通过框定查询结果的范围来得到想要的查询结果,SQL的体现上就是对于 t_id 的范围的框定。

四、其他

对于查询前10条数据中的第n条数据
以下是不同的写法,可以实现同样的效果,但是SQL却略微不同。
感兴趣的老铁可以自行研究研究

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第一条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME DESC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME DESC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 11
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME DESC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id - 9
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

-- 根据账号分组,时间倒叙排序,查询前10条数据中的第二条数据
SELECT t_all.* FROM (
SELECT (@s:=@s+1) AS t_id, t.* FROM t_user t, (SELECT @s:=0) t_table ORDER BY ACCOUNT, TIME DESC 
) t_all
INNER JOIN (
	SELECT max(a_id) a_id, ACCOUNT FROM (
		SELECT (@a:=@a+1) AS a_id, a.* FROM t_user a, (SELECT @a:=0) a_table ORDER BY ACCOUNT, TIME DESC 
	) tmp GROUP BY ACCOUNT
) a_all ON t_all.ACCOUNT = a_all.ACCOUNT AND t_all.t_id > a_all.a_id - 10
INNER JOIN (
	SELECT max(b_id) b_id, ACCOUNT FROM (
		SELECT (@b:=@b+1) AS b_id, b.* FROM t_user b, (SELECT @b:=0) b_table ORDER BY ACCOUNT, TIME DESC 
	) tmp GROUP BY ACCOUNT
) b_all ON t_all.ACCOUNT = b_all.ACCOUNT AND t_all.t_id < b_all.b_id - 8
ORDER BY t_all.ACCOUNT, t_all.TIME DESC;

参考链接:https://blog.csdn.net/wang1qqqq/article/details/117603407

OK,就这些吧。

有什么不对的还望指正,书写不易,觉得有帮助就点个赞吧!☺☺☺

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1408500.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据分析-Pandas如何用图把数据展示出来

数据分析-Pandas如何用图把数据展示出来 俗话说&#xff0c;一图胜千语&#xff0c;对人类而言一串数据很难立即洞察出什么&#xff0c;但如果展示图就能一眼看出来门道。数据整理后&#xff0c;如何画图&#xff0c;画出好的图在数据分析中成为关键的一环。 数据表&#xff…

【进入游戏行业选游戏特效还是技术美术?】

进入游戏行业选游戏特效还是技术美术&#xff1f; 游戏行业正处于蓬勃发展的黄金时期&#xff0c;科技的进步推动了游戏技术和视觉艺术的飞速革新。在这个创意和技术挑战交织的领域里&#xff0c;游戏特效和技术美术岗位成为了许多人追求的职业目标。 这两个岗位虽然紧密关联…

5.ROC-AUC机器学习模型性能的常用的评估指标

最近回顾机器学习基础知识部分的时候&#xff0c;看到了用于评估机器学习模型性能的ROC曲线。再次记录一下&#xff0c;想起之前学习的时候的茫然&#xff0c;希望这次可以更加清晰的了解这一指标。上课的时候听老师提起过&#xff0c;当时没有认真去看&#xff0c;所以这次可以…

硅像素传感器文献调研(八)

2000硅微带探测器的物理模拟&#xff1a;电极几何形状对临界电场的影响。 2000硅微带探测器的物理模拟&#xff1a;电极几何形状对临界电场的影响 摘要 本文介绍了交流耦合硅微带探测器的计算机分析。这项研究的目的是调查的主要几何参数负责潜在的关键影响&#xff0c;如早期…

【GitHub项目推荐--多功能 Steam 工具箱】【转载】

Steam 是一个开源跨平台的多功能 Steam 工具箱&#xff0c;此工具的大部分功能都是需要下载安装 Steam 才能使用。 功能包括网络加速、脚本配置、账号切换、库存管理、自动挂卡、游戏工具&#xff0c;比如强制游戏窗口使用无边框窗口化。 开源地址&#xff1a;https://github…

c++:类和对象(5),运算符重载

目录 运算符重载概念&#xff1a; 运算符重载 1.成员函数重载号 2.全局函数重载号 打印结果&#xff1a; <<运算符重载 递增运算符重载 简单例子 输出结果为&#xff1a; 赋值运算符重载 如何重载 输出结果为&#xff1a; 什么时候重载 关系运算符重载 简单例…

【并发编程】同步模式之保护性暂停

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程 ⛺️稳中求进&#xff0c;晒太阳 同步模式之保护性暂停 这个模式用到的基础就是wait-notify 详情可以看这篇文章》:【并发编程】wait/notify 即Guarded Suspension,用在一个线…

鸿蒙开发 状态管理

最近学习鸿蒙开发。 状态管理&#xff1a; State -> Prop 单向传递&#xff1b; stateprop: State -> Prop 单向传递 State -> Link 双向传递&#xff1b;

Windows脚本:监控并自动重启某个进程

Windows脚本&#xff1a;监控自动并重启某个进程 一、简介二 .bat脚本方式2.1 编制脚本2.2 创建并运行脚本2.3 设置关闭cmd窗口 三、使用VBScript脚本方式3.1 编制脚本3.2 运行脚本 四、设置脚本开机自启动五、某些软件加入启动项后&#xff0c;开机不会自动启动的解决方法 在实…

代码随想录算法训练营第十四天|二叉树基础-二叉树迭代-二叉树

文章目录 二叉树基础二叉树种类满二叉树完全二叉树二叉搜索树平衡二叉搜索树 二叉树的存储方式链式存储顺序存储 二叉树的遍历方式二叉树的定义 二叉树的递归遍历144.二叉树的前序遍历代码&#xff1a; 145.二叉树的后序遍历代码&#xff1a; 94. 二叉树的中序遍历代码 二叉树的…

Linux中并发程序设计

进程的创建和回收 进程概念 概念 程序 存放在磁盘上的指令和数据的有序集合&#xff08;文件&#xff09; 静态的 进程 执行一个程序所分配的资源的总称 动态的进程和程序比较 注&#xff1a;进程是存在RAM中&#xff0c;程序是存放在ROM(flash)中的进程内容 BSS段&#xff…

Unity通用渲染管线升级URP、HDRP

Unity通用渲染管线升级URP、HDRP 一、Build-in Pipline升级到 URP 一、Build-in Pipline升级到 URP 安装URP包 升级所有材质&#xff08;升级完成后材质会变成紫红色&#xff0c;Shader丢失&#xff0c;此为正常现象&#xff09; 创建 UniversalRenderPipelineAsset 配置文…

Origin:调整颜色刻度线间距和小数点

如何设置或修改Color Scale 的间距和小数位&#xff1f; 答&#xff1a;&#xff08;1&#xff09;更改间距&#xff1a;左键双击刻度标线——级别——“显示主刻度在”下选择自定义级别——在“值”输入自定义间距增量。 &#xff08;2&#xff09;更改小数点个数&#xff1a…

嵌入式-stm32-江科大-OLED调试工具

文章目录 一&#xff1a;OLED调试工具1.1 OLED显示屏介绍1.2 实验&#xff1a;在OLED显示屏的使用1.3 自己新增功能测试道友&#xff1a;今天没有开始的事&#xff0c;明天绝不会完成。 一&#xff1a;OLED调试工具 1.1 OLED显示屏介绍 学习任何一门语言就需要进行调试&#…

民用激光雷达行业简析

01. 激光雷达是“机器之眼” • 激光雷达是一个通过发射激光并接受发射激光同时对其进行信号处理&#xff0c;从而获得周边物体距离等信息的主动测量装置。 • 激光雷达主要由光发射、光扫描、光接收三大模块组成。光发射模块集成了驱动、开关和光源等芯片。光接收模块集成了…

浏览器安装证书,使用burp抓取任意https协议的流量

抓包显示都是http的。 接受风险后&#xff1a; 给burp加证书&#xff1a; 点击后会让你下载&#xff0c;证书已下载 证书长这个样子~~~ 浏览器设置中直接搜索证书&#xff1a; 勾选信任&#xff1a; 会到之前加载不出的页面刷新就可以看到加载出来图片等&#xff1a; 此时看到…

【大数据】Flink 系统架构

Flink 系统架构 1.Flink 组件1.1 JobManager1.2 ResourceManager1.3 TaskManager1.4 Dispatcher 2.应用部署2.1 框架模式2.2 库模式 3.任务执行4.高可用设置4.1 TaskManager 故障4.2 JobManager 故障 Flink 是一个用于状态化并行流处理的分布式系统。它的搭建涉及多个进程&…

服务器的组成

服务器的重要结构组成 家用电脑组成&#xff1a; CPU、主板、内存条、显卡、硬盘、电源、风扇、网卡、显示器、机箱、键盘鼠标等等。 CPU CPU是电脑的大脑&#xff0c; CPU发展史&#xff1a; 32 位CPU&#xff1a;最大的内存寻址地址2^32&#xff0c;大约4G的大小。 CP…

【基础算法练习】二分模板

文章目录 二分模板题二分的思想C 版本的二分整数二分模板 Golang 版本的二分整数二分模板 例题&#xff1a;在排序数组中查找元素的第一个和最后一个位置题目描述C 版本代码Golang 版本代码 二分模板题 704. 二分查找&#xff0c;这道题目是最经典的二分查找&#xff0c;使用于…

Git操作指南

Git操作指南 Git是一款非常强大的版本控制工具&#xff0c;可以帮助开发者管理代码的版本、协同开发以及进行代码的发布。以下是一些常见的Git操作指南。 基本操作 初始化一个Git仓库 git init添加文件到暂存区 git add 文件名提交更改到本地仓库 git commit -m "提…