MySQL 5.x/8.0 前無內置 ROW_NUMBER(),通過會話用戶變量 @rownum 實現結果集行號生成,適用於分頁定位、排名顯示、異常行定位。
SET @mycnt = 0;
SELECT
(@mycnt := @mycnt + 1) AS rownum,
othercol
FROM tblname
ORDER BY othercol;
@mycnt 會話級變量,連接斷開自動釋放。:= 賦值運算符,在 SELECT 列表中按行遞增。SET @mycnt = 0;
SELECT * FROM (
SELECT
(@mycnt := @mycnt + 1) AS rownum,
othercol
FROM tblname
ORDER BY othercol
) AS ranked
WHERE othercol = 'TargetValue';
返回該記錄在全量排序中的行號,避免應用層全量拉取計算。
CREATE TEMPORARY TABLE tmp_ranked (
rownum INT AUTO_INCREMENT PRIMARY KEY,
othercol VARCHAR(255)
) ENGINE=Memory;
INSERT INTO tmp_ranked (othercol)
SELECT othercol FROM tblname ORDER BY othercol;
SELECT * FROM tmp_ranked WHERE othercol = 'TargetValue';
| 方案 | 優點 | 缺點 |
|---|---|---|
| 用戶變量 | 無建表開銷、單語句完成、主從安全(不寫 Binlog) | 無法直接用於 WHERE/HAVING(需子查詢包裹)、8.0+ 建議用窗口函數 |
| 臨時表 AUTO_INCREMENT | 可直接 WHERE 過濾、行號持久化 | 主從複製可能不一致(臨時表不復制)、佔用內存/磁盤、需顯式 DROP |
SELECT
ROW_NUMBER() OVER (ORDER BY othercol) AS rownum,
othercol
FROM tblname;
行號生成是「分析型查詢」標配。變量法輕量、臨時表法重型、窗口函數法標準。按版本與場景選型,拒絕應用層全量拉取計算行號。