一.前言
眾所周知,Oracle有分析函數排名 rank()的功能,而Mysql并沒有,畢竟一分錢一分貨,花錢的自然有它的花錢的道理。但Mysql也能通過一些手段也能達到我們的需求
二.場景
一般排序場景的大致有3種
1.按照查詢條件從高到低,正常排序如1,2,3,...
2.按照查詢條件從高到低,允許并列排序如1,2,2,3,...
3.按照查詢條件從高到低,允許并列,但與排序號不同如1,2,2,4,...(較少見)
三.實現
主要還是貼實驗代碼,比較直觀
先建個測試表sql_rank
CREATE TABLE `sql_rank` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` INT(11) UNSIGNED NOT NULL,
`score` TINYINT(3) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB;
插入些測試數據
INSERT INTO sql_rank (user_id, score)
VALUES
(1, 50),
(2, 30),
(3, 20),
(4, 60),
(5, 80),
(6, 50),
(7, 70),
(8, 85),
(9, 60)
場景1
成績排名 -- 1 2 3 4 5 6
SELECT A.*, @rownum := @rownum + 1 AS rownum
FROM
(SELECT * FROM sql_rank ORDER BY score DESC) AS A,
(SELECT @rownum := 0) B
實驗結果如下:

1.jpg
場景2
成績排名-- 1 2 2 4 4 6
SELECT
s1.id,
s1.user_id,
s1.score,
(SELECT
COUNT(s.score) + 1
FROM
sql_rank s
WHERE s.score > s1.score) rank
FROM
sql_rank s1
WHERE s1.score IS NOT NULL
ORDER BY s1.score DESC
實驗結果如下:

2.jpg
場景3
成績排名-- 1 1 2 3 4 4 5
解法一:(較推薦)
SELECT score,
(SELECT COUNT(DISTINCT score) FROM sql_rank WHERE score >= s.`score`) AS rank
FROM sql_rank AS s ORDER BY score DESC
解法二:
SELECT score,
(SELECT
COUNT(*)
FROM
(SELECT DISTINCT
score AS s
FROM
sql_rank) AS new_score
WHERE s >= score) rank
FROM
sql_rank
ORDER BY score DESC
實驗結果如下:

3.jpg
小結:
在我們業(yè)務中有各種的排序需求,我們需要根據具體的業(yè)務來編寫相應的sql語句,此文章的總結也是剛好在工作有場景2的應用,查閱了度娘和谷哥,做了一些隨筆筆記。(侵刪,謝謝)