开发中常常会遇到,分组查询最新数据的问题,好比下面这张表(查询每一个地址最新的一条记录):mysql
sql以下: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
可是查询结果却不是咱们想要的:spa
执行时间按倒叙排列结果为:3d
因此真正想要获得的结果是id为2/8/11的记录,上面的查询获得的倒是1/5/9,这是为何呢?code
由于在mysql5.7的时候,子查询的排序已经变为无效了,多是由于子查询大多数是做为一个结果给主查询使用,因此子查询不须要排序的缘由。blog
那么咱们应该怎么查呢,有两种方式:排序
第一种:ci
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:第二种方式中最新的记录,不能同时地点和时间都相同,若是出现这种状况,第二种方式会查出把这两条记录都查出来,而第一条不会。
因此根据业务和数据状况来选择其中一种方式,毕竟效率差不太多。