需求:依欄位 aid 分組,取每組 day 最大值對應的完整記錄。
SELECT A.*
FROM test A
JOIN (
SELECT aid, MAX(day) AS max_day
FROM test
GROUP BY aid
) B ON A.aid = B.aid AND A.day = B.max_day
ORDER BY A.install DESC;
原理:衍生表 B 只含各組最大 day,再 JOIN 回主表取完整欄位。
SELECT * FROM test
WHERE (aid, day) IN (
SELECT aid, MAX(day) FROM test GROUP BY aid
);
MySQL 5.7+ 支援多欄 IN 子查詢,語意清晰。
SELECT * FROM table1 a
WHERE b = (SELECT MAX(b) FROM table1 WHERE a = a.a);
或使用 ROW_NUMBER() 窗口函數(MySQL 8.0+、PostgreSQL、SQL Server、Oracle):
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY aid ORDER BY day DESC) AS rn
FROM test
)
SELECT * FROM ranked WHERE rn = 1;
JOIN 與 IN 差異不大。(aid, day) 有複合索引,JOIN 通常優於相關子查詢。ROW_NUMBER(),可讀性與效能俱佳。CREATE TABLE test (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
install VARCHAR(50),
day INT UNSIGNED,
aid INT UNSIGNED
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO test (install, day, aid) VALUES
('www.111cn.net', 20120308, 1),
(2321, 20120309, 2),
(1236, 20120310, 3),
('www.111cn.net', 20120309, 1),
(2312, 20120310, 1),
(1432, 20120311, 1),
(2421, 20120308, 2),
(4245, 20120311, 2),
('www.111cn.net', 20120310, 2),
(412, 20120308, 3);
執行上述查詢,將得到每組 aid 最新 day 的完整列。