測試表test
class | name | score |
---|---|---|
1 | 張一 | 100 |
1 | 張二 | 99 |
1 | 張三 | 99 |
1 | 張四 | 98 |
1 | 張五 | 97 |
2 | 李一 | 100 |
2 | 李二 | 99 |
2 | 李三 | 98 |
2 | 李四 | 97 |
2 | 李五 | 96 |
排序(rank,dense_rank)
在 8.0 版本之前,參考了https://segmentfault.com/q/1010000011138138
- 使用臨時變量
-- 變量爲session級別,執行多次變量會累加,需要使用select @x:=0;將變量置0
SELECT
@x := ifnull( @x, 0 ) + 1 AS rownum,
score
FROM
test
ORDER BY
score DESC;
2.使用笛卡兒積
SELECT
a.NAME,
a.score,
count( * ) AS rownum
FROM
test a,
test b
WHERE
a.score <= b.score
GROUP BY
a.NAME,
a.score
ORDER BY
count( * ) ASC;
3. 使用子查詢
SELECT
a.*,
( SELECT count( * ) FROM test WHERE score >= a.score ) AS rownum
FROM
test a
ORDER BY
rownum ASC;
MySQL 8.0版本後
使用窗口函數不僅可以整體排序,還可以局部排序
-- 整體排序
SELECT
class,
score,
NAME,
rank() over ( ORDER BY score DESC ) AS rownum
FROM
test
ORDER BY
rownum;
-- 每個班級內部排名--RANK,相同值相同排名,排名不連續
SELECT
class,
score,
NAME,
RANK() over (PARTITION by class ORDER BY score DESC ) AS rownum
FROM
test
ORDER BY
class,rownum;
-- 每個班級內部排名--DENSE_RANK,相同值相同排名,排名連續
SELECT
class,
score,
NAME,
DENSE_RANK() over (PARTITION by class ORDER BY score DESC ) AS rownum
FROM
test
ORDER BY
class,rownum;
-- 每個班級內部排名--DENSE_RANK,相同值相同不同,排名連續
SELECT
class,
score,
NAME,
ROW_NUMBER() over (PARTITION by class ORDER BY score DESC ) AS rownum
FROM
test
ORDER BY
class,rownum;