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 ate_ate_time 通过MAX函数获取最新的时间和地址(因为需要按照地址分组),然后作为⼀张表和原来的数据进⾏联查,
条件就是地址和时间要和获取的最⼤时间和地址相等,此时结果为:
这两种⽅式的查询效率差不太多,第⼆种⽐第⼀种查询稍微快⼀点,可能是由于第⼆种⽅式的⼦查询只有两个字段(时间,被分组字段)的缘故吧!
感兴趣的可以照⼀张字段多的数据量⼤的表查询⼀下⽐较⽐较。
PS:第⼆种⽅式中最新的记录,不能同时地点和时间都相同,如果出现这种情况,第⼆种⽅式会查出把这两条记录都查出来,⽽第⼀条不会。
mysql group by order by所以根据业务和数据情况来选择其中⼀种⽅式,毕竟效率差不太多。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。