常見誤區:以為 GROUP BY id ORDER BY date DESC 配合 MAX(value1) 就能取得「日期最大那一行的 value1」。實則 MAX() 是逐欄獨立取最大,導致 value1、value2 可能來自不同行,產生錯誤業務結果。
無論資料庫版本,核心步驟只有兩步:
id + max(date) 或自增 row_id)。WITH Ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY date DESC) AS rn
FROM Records
)
SELECT id, date, value1, value2
FROM Ranked
WHERE rn = 1;
-- 衍生表 JOIN(最穩健)
SELECT r.id, r.date, r.value1, r.value2
FROM Records r
JOIN (
SELECT id, MAX(date) AS max_date
FROM Records
GROUP BY id
) g ON r.id = g.id AND r.date = g.max_date;
CREATE INDEX IX_Records_Id_Date_Cover ON Records(id, date DESC) INCLUDE (value1, value2);
有了覆蓋索引,無論子查詢、JOIN、CTE,執行計劃皆為 Index Seek + Stream Aggregate,毫秒級返回。
記住:分組排序取整行 = 先算分組鍵 + 最大排序鍵,再 JOIN 回主表,別再被 MAX(column) 逐欄拆解的假象誤導。