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

一、记录

记录一次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.mzph.cn/news/644500.shtml

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

相关文章

力扣刷题第十天 美丽塔 一

给你一个长度为 n 下标从 0 开始的整数数组 maxHeights 。 你的任务是在坐标轴上建 n 座塔。第 i 座塔的下标为 i &#xff0c;高度为 heights[i] 。 如果以下条件满足&#xff0c;我们称这些塔是 美丽 的&#xff1a; 1 < heights[i] < maxHeights[i]heights 是一个 山脉…

开发知识点-Flutter移动应用开发

支持 安卓 IOS Android 鸿蒙 第一章dart基础章节介绍 移动电商——Flutter-广告Banner组件制作 移动电商——Flutter实战课程介绍 Flutter实例——路由跳转的动画效果

Elment UI的el-table-column表头旁边有点击按钮类似的操作

Elment UI的el-table-column表头旁边有点击按钮类似的操作 <el-table-column fixed"right" label"操作" ><!-- 表头 --> {{-- <template slot"header" header"scope">--}} {{-- <span…

精通 VS 调试技巧,学习与工作效率翻倍!

​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ ​ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; ​ 所属专栏&#xff1a;C语言学习 ​ 贝蒂的主页&#xff1a;Betty‘s blog 1. 什么是调试 当我们写代码时候常常会遇见输出结果不符合我们预…

基于开源库imu_gps_localization进行组合导航

文章目录 概要数据准备准备工作运行复现结果参考概要 利用imu和GPS数据进行组合导航,在我的数据集上复现效果较差。 数据准备 https://github.com/ucr-robotics/citrus-farm-dataset 准备工作 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com…

not eligible for auto-proxying

​ 异常分析 异常信息 is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)异常触发 int beanProcessorTargetCount beanFactory.getBeanPostProcessorCount() 1 postProcessorNames.length;beanFactory.a…

单轴测径仪在线缆电缆测控中的应用

线缆电缆在生产中能进行品质测量与控制&#xff0c;对其生产模式而言&#xff0c;是更为合适的&#xff0c;毕竟其生产模式决定了其任何品质问题出现都会造成产品的品质下降或不合格。要想进行生产高品质的产品&#xff0c;对产线的要求较高。 单轴测径仪作为测控一体&#xff…

转义特殊字符——printf命令、sed命令

shell脚本中,一些字符串引用了特殊字符,但不能通过单引号原样输出,这时候就需要通过转义符对特殊符号进行转义。 printf命令——转义特殊字符 printf 命令是一个用于格式化输出的命令,可以根据指定的格式字符串和参数输出格式化的文本。 printf %q [参数列表]%q 是 pr…

安卓开发之自动缩放布局

AutoScalingLayout 适用于 Android 的自动缩放布局。 替换布局&#xff1a; 我们只需要替换根布局所需的自动缩放&#xff0c;子布局也将实现自动缩放。 原始布局AutoScalingLayout相对布局ASRelativeLayout线性布局ASLinearLayoutFrameLayout&#xff08;框架布局&#xff…

项目一:踏上Java开发之旅

文章目录 一、实战概述二、实战步骤任务1&#xff1a;安装配置JDK并开发第一个Java程序步骤一&#xff1a;安装JDK步骤二&#xff1a;配置JDK环境变量步骤三&#xff1a;开发第一个Java程序 课堂练习任务1、打印个人信息任务2、打印直角三角形任务3、打印一颗爱心任务4、打印史…

Linux服务器系统修改SSH端口教程

修改端口号是通过修改SSH的配置文件实现的&#xff0c;在服务器终端先激活root用户&#xff0c;然后输入&#xff1a; vim /etc/ssh/sshd_config找到#Port 22这个位置 键盘按i进入编辑模式 删除掉Port 22前面的#&#xff0c;然后键盘按一下回车键&#xff08;如果没有#可不必…

记一次SPI机制导致的BUG定位【不支持:http://javax.xml.XMLConstants/property/accessExternalDTD】

1、前因 今天在生产环境启用了某个功能&#xff0c;结果发现有个文件上传华为云OBS失败了&#xff0c;报错如下&#xff1a; Caused by: java.lang.IllegalArgumentException: 不支持&#xff1a;http://javax.xml.XMLConstants/property/accessExternalDTDat org.apache.xal…

C++参悟:数值运算相关

数值运算相关 一、概述二、常用数学函数1. 基础运算1. 浮点值的绝对值&#xff08; |x| &#xff09;2. 浮点除法运算的余数3. 除法运算的有符号余数4. 除法运算的有符号余数和最后三个二进制位5. 混合的乘加运算6. 两个浮点值的较大者7. 两个浮点值的较小者8. 两个浮点值的正数…

Grafana loki配置, 无脑版

使用docker部署Grafana loki 1.创建 docker-compose.yml 文件 touch docker-compose.yml写入以下内容 vim touch docker-compose.yml version: "3"networks:loki:services:loki:image: grafana/loki:latestrestart: unless-stoppedports:- "3100:3100"vo…

LeetCode 14.最长公共前缀(python版)

需求 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例 1&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”] 输出&#xff1a;“fl” 示例 2&#xff1a; 输入&#xff1a;strs [“dog”,“race…

【高效开发工具系列】Intellj IDEA 2023.3 版本

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

curl命令导致你下载的文件为空原因分析

文章目录 1.前言2. 通过curl -O 下载远端文件2.1 执行curl -O下载远端文件2.2 通过curl -v 查看详细的请求和响应的信息 3.通过在curl -O 中增加 -L 参数保证curl能够自动跟踪和请求远端返回的重定向地址4.结论 1.前言 最近在进行线上项目调试的过程中需要安装调试工具&#xf…

HubSpot能不能对接微信公众号?

在当今数字化时代&#xff0c;企业的数字化营销策略不可或缺。其中&#xff0c;HubSpot作为一体化营销平台&#xff0c;是否能与国内最大的社交平台之一——微信公众号进行无缝对接&#xff0c;成为业界关注的焦点。今天运营坛将深入探讨HubSpot与微信公众号的对接流程、Messag…

【Java万花筒】解码Java网络通讯谜团:对比Apache HttpClient、OkHttp、Feign、RestTemplate、Retrofit

Java网络请求大比拼&#xff1a;HttpClient、OkHttp、Feign、RestTemplate、Retrofit全面解析 前言 在当今互联网时代&#xff0c;Java开发者常常需要处理与各种RESTful服务的通信。本文旨在深入比较Java中几个主流的网络请求库&#xff0c;包括Apache HttpClient、OkHttp、F…

【华为 ICT HCIA eNSP 习题汇总】——题目集6

1、IEEE 802.11g 标准支持的最大协商速率为&#xff08;&#xff09;。 A、300Mbps B、150Mbps C、54Mbps D、1200Mbps 考点&#xff1a;无线局域网 解析&#xff1a;&#xff08;C&#xff09; IEEE 802.11系列标准如下表&#xff1a; 标准数据传输速率主要技术IEEE 802.111M…