日誌表 Log(Grp, CreateTime, ...),每群組 (Grp) 依時間倒序取最新一筆。
SELECT * FROM Log T WHERE Id = ( SELECT TOP 1 Id FROM Log WHERE Grp = T.Grp ORDER BY CreateTime DESC );
WITH Ranked AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Grp ORDER BY CreateTime DESC) AS Rn FROM Log ) SELECT * FROM Ranked WHERE Rn = 1;
SELECT TOP 1 WITH TIES * FROM Log ORDER BY ROW_NUMBER() OVER (PARTITION BY Grp ORDER BY CreateTime DESC);
SELECT * FROM (
SELECT
Type, Code,
ROW_NUMBER() OVER (PARTITION BY Type ORDER BY Code) AS Rn
FROM Group_Info
) WHERE Rn = 1;
SELECT Type, MIN(Code) FROM Group_Info GROUP BY Type;
注意:SELECT 清單非聚合欄位必須在 GROUP BY 或包裹聚合函數,否則 ORA-00979。
SELECT * FROM Log ORDER BY CreateTime DESC LIMIT 0, 1;
WITH Ranked AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Grp ORDER BY CreateTime DESC) AS Rn FROM Log ) SELECT * FROM Ranked WHERE Rn = 1;
SELECT Grp, CreateTime, Data FROM (
SELECT
Grp, CreateTime, Data,
@rn := IF(@prev = Grp, @rn + 1, 1) AS Rn,
@prev := Grp
FROM Log
CROSS JOIN (SELECT @rn := 0, @prev := NULL) vars
ORDER BY Grp, CreateTime DESC
) T WHERE Rn = 1;
| 平台 | 標準視窗函數 | 舊版替代 | 備註 |
|---|---|---|---|
| SQL Server | ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) (2005+) | 相關子查詢 TOP 1 | CTE 寫法最清晰 |
| Oracle | ROW_NUMBER() OVER (...) (8i+) | MIN/MAX 聚合 (僅鍵值) | 分析函數成熟 |
| PostgreSQL | ROW_NUMBER() OVER (...) (8.4+) | DISTINCT ON (Grp) ORDER BY Grp, CreateTime DESC | DISTINCT ON 為 PG 獨有簡潔語法 |
| MySQL | ROW_NUMBER() OVER (...) (8.0+) | 用戶變數模擬 | 5.7 升級 8.0 即可用標準寫法 |
Grp) + 排序欄位 (CreateTime) 建立複合索引 (Grp, CreateTime DESC)。ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...) 是 ANSI SQL 標準、跨平台通用的「每群組 Top-N」解法。SQL Server 2005+、Oracle 8i+、PostgreSQL 8.4+、MySQL 8.0+ 均完整支援。舊版平台以相關子查詢或廠商特有語法 (DISTINCT ON) 替代。統一採用標準視窗函數,提升可移植性與可維護性。