MySQL分组查询每组最新的一条数据(通俗易懂)

时间:2022-08-23 16:33:10

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

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

但是查询结果却不是我们想要的:

MySQL分组查询每组最新的一条数据(通俗易懂)

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

MySQL分组查询每组最新的一条数据(通俗易懂)

所以真正想要得到的结果是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

结果为:

MySQL分组查询每组最新的一条数据(通俗易懂)

对子查询的排序进行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函数获取最新的时间和地址(因为需要按照地址分组),然后作为一张表和原来的数据进行联查,

条件就是地址和时间要和获取的最大时间和地址相等,此时结果为:

MySQL分组查询每组最新的一条数据(通俗易懂)

这两种方式的查询效率差不太多,第二种比第一种查询稍微快一点,可能是由于第二种方式的子查询只有两个字段(时间,被分组字段)的缘故吧!

感兴趣的可以照一张字段多的数据量大的表查询一下比较比较。

PS:第二种方式中最新的记录,不能同时地点和时间都相同,如果出现这种情况,第二种方式会查出把这两条记录都查出来,而第一条不会。

所以根据业务和数据情况来选择其中一种方式,毕竟效率差不太多。

MySQL分组查询每组最新的一条数据(通俗易懂)的更多相关文章

  1. mysql分组查询获取组内某字段最大的记录

    id sid cid 1 1 12 1 23 2 1 以sid分组,最后取cid最大的那一条,以上要取第2.3条 1 方法一: select * from (select * from table o ...

  2. MySQL分组查询获取每个学生前n条分数记录(分组查询前n条记录)

    CREATE TABLE `t_test` ( `id` ) NOT NULL AUTO_INCREMENT, `stuid` ) NOT NULL, `score` ) DEFAULT NULL, ...

  3. mysql 分组查询

    mysql 分组查询 获取id最大的一条 (1)分组查询获取最大id SELECT MAX(id) as maxId FROM `d_table` GROUP BY `parent_id` ; (2) ...

  4. Oracle和MySQL分组查询GROUP BY

    Oracle和MySQL分组查询GROUP BY 真题1.Oracle和MySQL中的分组(GROUP BY)有什么区别? 答案:Oracle对于GROUP BY是严格的,所有要SELECT出来的字段 ...

  5. sql 分组取每组的前n条或每组的n%(百分之n)的数据

    sql 分组取每组的前n条或每组的n%(百分之n)的数据 sql keyword: SELECT * ,ROW_NUMBER() OVER(partition by b.UserID order by ...

  6. 转: 从Mysql某一表中随机读取n条数据的SQL查询语句

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...

  7. Mysql 保留最新的10条数据

    Mysql每天执行计划,保留最新的10条数据,其余的删除 1.Mysql 保留最新的10条数据 sql语句: DELETE tb FROM tbname AS tb,( SELECT id FROM ...

  8. sql 查询某个条件多条数据中最新的一条数据或最老的一条数据

    sql 查询某个条件下多条数据中最新的一条数据或最老的一条数据 test_user表结构如下: 需求:查询李四.王五.李二创建的最初时间或者最新时间 1:查询最初的创建时间: SELECT * FRO ...

  9. 从Mysql某一表中随机读取n条数据的SQL查询语句

    若要在i ≤ R ≤ j 这个范围得到一个随机整数R ,需要用到表达式 FLOOR(i + RAND() * (j – i + 1)).例如, 若要在7 到 12 的范围(包括7和12)内得到一个随机 ...

随机推荐

  1. jemter的安装和使用

    1.下载地址:http://jmeter.apache.org/download_jmeter.cgi 2.安装 (1)解压,解压之后如图 (2)配置环境变量 我解压之后的目录是:D:\softwar ...

  2. Selenium定位二 --多个元素定位方法 和层级定位方法

    定位多个元素: findElements()方法可以返回一个符合条件的元素List 组 如: public void hitUpdatePersonnel(WebDriver driver, int ...

  3. underscorejs-map学习

    2.2 map 2.2.1 语法: _.map(list, iteratee, [context]) 2.2.2 说明: 对集合的每个成员依次进行某种操作,将返回的值依次存入一个新的数组.接收3个参数 ...

  4. xcode中控件共有属性

    Text,title 控件上的文字 backgroung 背景图片或颜色 alignment 布局(居中,..) mode显示模式(缩放,拉伸..) drawing 隐藏控件的可见性 alpha 透明 ...

  5. ReentrantLock源码分析与理解

    在上面一篇分析ThreadExecutedPool的文章中我们看到线程池实现源码中大量使用了ReentrantLock锁,那么ReentrantLock锁的优势是什么?它又是怎么实现的呢? Reent ...

  6. vue实例讲解之axios的使用

    本篇来讲解一下axios插件的使用,axios是用来做数据交互的插件. 这篇将基于vue实例讲解之vue-router的使用这个项目的源码进行拓展. axios的使用步骤: 1.安装axios npm ...

  7. vue2.0父子组件之间通信

    父组件是通过props属性给子组件通信的来看下代码: 父组件: <parent> <child :child-com="content"></chil ...

  8. Linux IO 模型

    Linux 中主要有五种IO模式:阻塞IO, 非阻塞IO, IO 多路复用,信号驱动IO和异步IO; 如果从同步非同步,阻塞非阻塞角度来看,又可以分为:同步阻塞IO, 同步非阻塞IO,异步阻塞IO和异 ...

  9. Android必学-异步加载&plus;Android自定义View源码【申明:来源于网络】

    Android必学-异步加载+Android自定义View源码[申明:来源于网络] 异步加载地址:http://download.csdn.net/detail/u013792369/8867609 ...

  10. &lbrack;转&rsqb;Linux联网问题

    一.Kali联网问题 首先ifconfig,可以看到没有正在工作的网卡,只有localhost 然后ifconfig -a,可以看到eth0这块网卡并没有离家出走,只是罢工了而已 打开/etc/net ...