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:第二種方式中最新的記錄,不能同時地點和時間都相同,如果出現這種情況,第二種方式會查出把這兩條記錄都查出來,而第一條不會。

所以根據業務和數據情況來選擇其中一種方式,畢竟效率差不太多。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM