表 t1 無主鍵,userid 重複,需取每個 userid 時間最近(atime 最大)的一筆。常規做法需臨時表或 JOIN,這裡介紹單一查詢技巧:GROUP_CONCAT + SUBSTRING_INDEX。
CREATE TABLE `t1` ( `userid` int(11) DEFAULT NULL, `atime` datetime DEFAULT NULL, KEY `idx_userid` (`userid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES (1, '2013-08-12 11:05:25'), (2, '2013-08-12 11:05:29'), (3, '2013-08-12 11:05:32'), (5, '2013-08-12 11:05:34'), (1, '2013-08-12 11:05:40'), (2, '2013-08-12 11:05:43'), (3, '2013-08-12 11:05:48'), (5, '2013-08-12 11:06:03');
SELECT userid,
SUBSTRING_INDEX(GROUP_CONCAT(atime ORDER BY atime DESC), ',', 1) AS atime
FROM t1
GROUP BY userid;
+--------+---------------------+ | userid | atime | +--------+---------------------+ | 1 | 2013-08-12 11:05:40 | | 2 | 2013-08-12 11:05:43 | | 3 | 2013-08-12 11:05:48 | | 5 | 2013-08-12 11:06:03 | +--------+---------------------+
GROUP_CONCAT(atime ORDER BY atime DESC):各群組內將時間按降序串聯成字串,如 '2013-08-12 11:05:40,2013-08-12 11:05:25'。SUBSTRING_INDEX(..., ',', 1):取第一個逗號前的子串,即最大時間值。SET SESSION group_concat_max_len = 1000000;。ROW_NUMBER() OVER (PARTITION BY userid ORDER BY atime DESC),語義更清晰、效能更穩定。MAX(atime) 關聯回原表。此技巧適用於快速分析、資料量中等、不想建立臨時表的場景。