經典需求:按userid, classid分組,每組保留addtime最新的一條(去重)。標準SQL用窗口函數ROW_NUMBER()優雅解決,適用於PostgreSQL、SQL Server、Oracle、MySQL 8.0+。
SELECT * FROM (
SELECT
userid,
classid,
remark,
ROW_NUMBER() OVER (
PARTITION BY userid, classid
ORDER BY addtime DESC
) AS row_bank
FROM Eng24VIPCourseIntention
) AS ta
WHERE row_bank = 1;
| 子句 | 作用 |
|---|---|
PARTITION BY userid, classid | 分組鍵:相同userid+classid歸為一組 |
ORDER BY addtime DESC | 組內排序:最新時間排第一(row_number=1) |
ROW_NUMBER() | 生成組內連續序號 1,2,3... |
| WHERE row_bank = 1 | 過濾:僅保留每組第一行(最新) |
SELECT t1.* FROM Eng24VIPCourseIntention t1
JOIN (
SELECT userid, classid, MAX(addtime) AS max_time
FROM Eng24VIPCourseIntention
GROUP BY userid, classid
) t2 ON t1.userid = t2.userid AND t1.classid = t2.classid AND t1.addtime = t2.max_time;
SELECT userid, classid, remark FROM (
SELECT
userid, classid, remark,
@rn := IF(@prev = CONCAT(userid, classid), @rn + 1, 1) AS rn,
@prev := CONCAT(userid, classid)
FROM Eng24VIPCourseIntention
CROSS JOIN (SELECT @rn := 0, @prev := '') vars
ORDER BY userid, classid, addtime DESC
) t WHERE rn = 1;
ORDER BY addtime ASCORDER BY score DESCPARTITION BY a, b, cCREATE TEMPORARY TABLE分區處理(userid, classid, addtime)有聯合索引,支援PARTITION BY與ORDER BY下推WHERE addtime > '2023-01-01'減少參與行數窗口函數讓「分組Top-N」從「多層嵌套子查詢」進化為「單層線性邏輯」,是現代SQL必備技能。