MySQL分组查询每组最新的一条数据(通俗易懂)
开发中经常会遇到,分组查询最新数据的问题,比如下面这张表(查询每个地址最新的一条记录):

sql如下:
-- ----------------------------
-- Table structure for test
-- ----------------------------
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`address` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`create_time` timestamp(0) NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ----------------------------
-- Records of test
-- ----------------------------
INSERT INTO `test` VALUES (1, '张三1', '北京', '2019-09-10 11:22:23');
INSERT INTO `test` VALUES (2, '张三2', '北京', '2019-09-10 12:22:23');
INSERT INTO `test` VALUES (3, '张三3', '北京', '2019-09-05 12:22:23');
INSERT INTO `test` VALUES (4, '张三4', '北京', '2019-09-06 12:22:23');
INSERT INTO `test` VALUES (5, '李四1', '上海', '2019-09-06 12:22:23');
INSERT INTO `test` VALUES (6, '李四2', '上海', '2019-09-07 12:22:23');
INSERT INTO `test` VALUES (7, '李四3', '上海', '2019-09-11 12:22:23');
INSERT INTO `test` VALUES (8, '李四4', '上海', '2019-09-12 12:22:23');
INSERT INTO `test` VALUES (9, '王二1', '广州', '2019-09-03 12:22:23');
INSERT INTO `test` VALUES (10, '王二2', '广州', '2019-09-04 12:22:23');
INSERT INTO `test` VALUES (11, '王二3', '广州', '2019-09-05 12:22:23');
平常我们会进行按照时间倒叙排列然后进行分组,获取每个地址的最新记录,sql如下:
SELECT * FROM(SELECT * FROM test ORDER BY create_time DESC) a GROUP BY address
但是查询结果却不是我们想要的:

执行时间按倒叙排列结果为:

所以真正想要得到的结果是id为2/8/11的记录,上面的查询得到的却是1/5/9,这是为什么呢?
因为在mysql5.7的时候,子查询的排序已经变为无效了,可能是因为子查询大多数是作为一个结果给主查询使用,所以子查询不需要排序的原因。
那么我们应该怎么查呢,有两种方式:
第一种:
SELECT * FROM(SELECT * FROM test ORDER BY create_time DESC LIMIT 10000) a GROUP BY address
结果为:

对子查询的排序进行limit限制,此时子查询就不光是排序,所以此时排序会生效,但是限制条数却只能尽可能的设置大些
第二种:
SELECT t.* FROM (SELECT address,max(create_time) as create_time FROM test GROUP BY address) a LEFT JOIN test t ON t.address=a.address and t.create_time=a.create_time
通过MAX函数获取最新的时间和地址(因为需要按照地址分组),然后作为一张表和原来的数据进行联查,
条件就是地址和时间要和获取的最大时间和地址相等,此时结果为:

这两种方式的查询效率差不太多,第二种比第一种查询稍微快一点,可能是由于第二种方式的子查询只有两个字段(时间,被分组字段)的缘故吧!
感兴趣的可以照一张字段多的数据量大的表查询一下比较比较。
PS:第二种方式中最新的记录,不能同时地点和时间都相同,如果出现这种情况,第二种方式会查出把这两条记录都查出来,而第一条不会。
所以根据业务和数据情况来选择其中一种方式,毕竟效率差不太多。
MySQL分组查询每组最新的一条数据(通俗易懂)的更多相关文章
- mysql分组查询获取组内某字段最大的记录
id sid cid 1 1 12 1 23 2 1 以sid分组,最后取cid最大的那一条,以上要取第2.3条 1 方法一: select * from (select * from table o ...
- MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)
CREATE TABLE `t_test` ( `id` ) NOT NULL AUTO_INCREMENT, `stuid` ) NOT NULL, `score` ) DEFAULT NULL, ...
- mysql 分组查询
mysql 分组查询 获取id最大的一条 (1)分组查询获取最大id SELECT MAX(id) as maxId FROM `d_table` GROUP BY `parent_id` ; (2) ...
- Oracle和MySQL分组查询GROUP BY
Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别? 答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段 ...
- sql 分组取每组的前n条或每组的n%(百分之n)的数据
sql 分组取每组的前n条或每组的n%(百分之n)的数据 sql keyword: SELECT * ,ROW_NUMBER() OVER(partition by b.UserID order by ...
- 转: 从Mysql某一表中随机读取n条数据的SQL查询语句
若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...
- Mysql 保留最新的10条数据
Mysql每天执行计划,保留最新的10条数据,其余的删除 1.Mysql 保留最新的10条数据 sql语句: DELETE tb FROM tbname AS tb,( SELECT id FROM ...
- sql 查询某个条件多条数据中最新的一条数据或最老的一条数据
sql 查询某个条件下多条数据中最新的一条数据或最老的一条数据 test_user表结构如下: 需求:查询李四.王五.李二创建的最初时间或者最新时间 1:查询最初的创建时间: SELECT * FRO ...
- 从Mysql某一表中随机读取n条数据的SQL查询语句
若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...
随机推荐
- Sword 哈希表
哈希表 哈希表是一种典型的以空间换取时间的数据结构,在没有冲突的情况下,对任意元素的插入.索引.删除的时间复杂度都是O().这样优秀的时间复杂度是通过将元素的key值以hash方法f映射到哈希表中的某 ...
- Java12新特性 -- 默认生成类数据共享(CDS)归档文件
默认生成类数据共享(CDS)归档文件 同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内 存占用是比较高的.所以Java团队引入了类数据共享机制 (Clas ...
- 深入理解JVM虚拟机
JVM平台上还可以运行其他语言,运行的是Class字节码.只要能翻译成Class的语言就OK了.挺强大的. JVM厂商很多 垃圾收集器.收集算法 JVM检测工具 关于类的加载: Java代码中,类型( ...
- vc对话框程序运行时隐藏
1.在资源编辑中设置对话框为不可见 2.在OnPaint中加入下面代码 void CMyDlg::OnPaint() { static b = false; if(!b){ ShowWindow(SW ...
- springboot 80转443
application.yml 中配置https证书信息 向spring容器中注入两个Bean,代码如下 import java.util.Map; import org.apache.catalin ...
- Java进程故障排查思路及步骤
故障场景 Java进程出现问题,通常表现出如下现象: Web应用响应时间长/超时,甚至不响应 CPU使用率极高/低,频繁出现Full GC,甚至OutOfMemoryError 响应时间长.超时,甚至 ...
- Java生成艺术二维码也可以很简单
原文点击: Quick-Media Java生成艺术二维码也可以很简单 现在二维码可以说非常常见了,当然我们见得多的一般是白底黑块,有的再中间加一个 logo,或者将二维码嵌在一张特定的背景中(比如微 ...
- time 库
time 库的三类函数 时间获取: >>> import time >>> time.time() 1570150181.4052463#单位为秒 >> ...
- Delphi文字转语音TTS【支持选择语音库,播放,暂停,开始,停止,生成语音文件,设置音量,设置语速】
作者QQ:(648437169) 点击下载➨文字转语音TTS [Delphi 文字转语音TTS]调用系统自带的TTS组件,支持XP,vista,win7,win8,win10系统,支持选择语音库,播放 ...
- CLRS10.1-7练习 - 用双队列实现栈
算法中心思想: 始终向非空队列进行入队操作 初始化时两个队列都为空,我们对q1进行入队操作 入栈: 只需执行其中一个队列入队操作即可, 具体操作哪一个队列,用一个标记变量标记 出栈流程图 代码实现 p ...