表 Eng24VIPCourseIntention 記錄用戶課程意向,同一 userid + classid 可能有多筆記錄(重複提交、歷史變更),需**保留每組最新一筆**(按 addtime DESC)。
SELECT *
FROM (
SELECT
userid,
classid,
remark,
ROW_NUMBER() OVER (
PARTITION BY userid, classid
ORDER BY addtime DESC
) AS row_rank
FROM Eng24VIPCourseIntention
) AS t
WHERE row_rank = 1;
| 子句 | 作用 |
|---|---|
PARTITION BY userid, classid | 分群鍵:同一用戶同一課程為一組 |
ORDER BY addtime DESC | 組內排序:最新在前 |
ROW_NUMBER() | 組內依序編號 1,2,3... |
WHERE row_rank = 1 | 只保留每組第一行(最新) |
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;
PARTITION BY 欄位有索引,或建立 (userid, classid, addtime DESC) 覆蓋索引。CREATE TEMPORARY TABLE 存中間結果再過濾。ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 是現代 SQL 去重保留最新/最舊/最高/最低的**標準寫法**,語意清晰、效能優異、跨資料庫通用。MySQL 8.0+ 請放心大膽用。