MySQL 5.1/5.5/5.6 均無原生 ROWNUM 或 ROW_NUMBER()(8.0 才支持窗口函數)。常見替代方案:
CREATE TABLE tbl (id INT PRIMARY KEY, col INT);
INSERT INTO tbl VALUES (1,26),(2,46),(3,35),(4,68),(5,93),(6,92);
-- 按 col 排序後期望行號:1→26, 2→35, 3→46, 4→68, 5→92, 6→93
# PHP/Python/Java 等
row_num = 0
while row = fetch():
row_num += 1
print(row_num, row)
SET @rownum := 0;
SELECT @rownum := @rownum + 1 AS rownum, id, col
FROM tbl ORDER BY col;
SET @rownum=0SELECT a.id, a.col, COUNT(*) AS rownum
FROM tbl a JOIN tbl b ON a.col >= b.col
GROUP BY a.id, a.col
ORDER BY a.col;
SELECT a.*,
(SELECT COUNT(*) FROM tbl WHERE col <= a.col) AS rownum
FROM tbl a
ORDER BY a.col;
| 方案 | 耗時 | 備註 |
|---|---|---|
| 應用層 | ~0ms | 最快 |
| 用戶變量 | 0.00 sec | 極快,但需注意連接池 |
| 自連接 | 0.00 sec | 小數據可接受 |
| 子查詢 | 0.06 sec | 最慢 |
SELECT id, col,
ROW_NUMBER() OVER (ORDER BY col) AS rownum,
RANK() OVER (ORDER BY col) AS rnk,
DENSE_RANK() OVER (ORDER BY col) AS drnk
FROM tbl;
PARTITION BY 分組行號ORDER BY 子查詢保證順序:SELECT @rn:=@rn+1 rownum, id, col FROM (SELECT id, col FROM tbl ORDER BY col) t, (SELECT @rn:=0) r;