MySQL分組查詢每組最新的一條數據(通俗易懂)

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

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

相關文章
相關標籤/搜索