開發中常常會遇到,分組查詢最新數據的問題,好比下面這張表(查詢每一個地址最新的一條記錄):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:第二種方式中最新的記錄,不能同時地點和時間都相同,若是出現這種狀況,第二種方式會查出把這兩條記錄都查出來,而第一條不會。
因此根據業務和數據狀況來選擇其中一種方式,畢竟效率差不太多。