mysql計算排名 轉


from :http://www.cnblogs.com/aeiou/p/5719396.html 

            http://www.cnblogs.com/zengguowang/p/5541431.html

 

mysql計算排名,獲取行號rowno

學生成績表數據

SELECT * FROM table_score ORDER BY score DESC;

 

獲取某個學生成績排名並計算該學生和上一名學生成績差,是並列排名

SELECT *,
(SELECT count(DISTINCT score) FROM table_score AS b WHERE a.score<b.score)+1 AS rank, #獲取排名,並列
(SELECT b.score FROM table_score AS b WHERE b.score>a.score ORDER BY b.score LIMIT 1)-a.score AS subtract #獲取和上一名學生成績的差 
FROM table_score AS a WHERE a.s_id = 13; #獲取學生周三的成績排名和與上一名的成績差

 

獲取所有學生成績排名-並列排名

SELECT *,
(SELECT count(DISTINCT score) FROM table_score AS b WHERE a.score<b.score)+1 AS rank #獲取排名-並列
FROM table_score AS a ORDER BY rank; #獲取學生成績排名

 

獲取所有學生成績排名,不是並列排名。計算行號進行排名

SELECT a.*,
(@rowNum:=@rowNum+1) AS rank #計算行號FROM table_score AS a,
(SELECT (@rowNum :=0) ) b
ORDER BY a.score DESC;

 

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

sql語句查詢排名

思路:有點類似循環里面的自增一樣,設置一個變量並賦予初始值,循環一次自增加1,從而實現排序;

   mysql里則是需要先將數據查詢出來並先行按照需要排序的字段做好降序desc,或則升序asc,設置好排序的變量(初始值為0):

   a>.將已經排序好的數據從第一條依次取出來,取一條就自增加一,實現從1到最后的一個排名

   b>.當出現相同的數據時,排名保持不變,此時則需要再設置一個變量,用來記錄上一條數據的值,跟當前數據的值進行對比,如果相同,則排名不變,不相同則排名自增加1

   c.當出現相同的數據時,排名保持不變,但是保持不變的排名依舊會占用一個位置,也就是類似於(1,2,2,2,5)這種排名就是屬於中間的三個排名是一樣的,但是第五個排名按照上面一種情況是(1,2,2,2,3),現在則是排名相同也會占據排名的位置

 

准備數據(用戶id,分數):

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,
`add_time` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

 

插入數據:

INSERT INTO sql_rank (user_id, score, add_time)
VALUES
(100, 50, '2016-05-01'),
(101, 30, '2016-05-01'),
(102, 20, '2016-05-01'),
(103, 60, '2016-05-01'),
(104, 80, '2016-05-01'),
(105, 50, '2016-05-01'),
(106, 70, '2016-05-01'),
(107, 85, '2016-05-01'),
(108, 60, '2016-05-01')

 

當前數據庫數據:

一、sql1{不管數據相同與否,排名依次排序(1,2,3,4,5,6,7.....)}

復制代碼
SELECT
    obj.user_id,obj.score,@rownum := @rownum + 1 AS rownum
FROM
    (
        SELECT
            user_id,
            score
        FROM
            `sql_rank`
        ORDER BY
            score DESC
    ) AS obj,
    (SELECT @rownum := 0) r
復制代碼

執行的結果如下圖:

  

可以看到,現在按照分數從1到9都排好序了,但是有些分數相同的用戶排名卻不一樣,這就是接下來要說的第二種sql

二、sql2{只要數據有相同的排名就一樣,排名依次排序(1,2,2,3,3,4,5.....)}

復制代碼
SELECT
    obj.user_id,
    obj.score,
    CASE
WHEN @rowtotal = obj.score THEN
    @rownum
WHEN @rowtotal := obj.score THEN
    @rownum :=@rownum + 1
WHEN @rowtotal = 0 THEN
    @rownum :=@rownum + 1
END AS rownum
FROM
    (
        SELECT
            user_id,
            score
        FROM
            `sql_rank`
        ORDER BY
            score DESC
    ) AS obj,
    (SELECT @rownum := 0 ,@rowtotal := NULL) r
復制代碼

這時候就新增加了一個變量,用於記錄上一條數據的分數了,只要當前數據分數跟上一條數據的分數比較,相同分數的排名就不變,不相同分數的排名就加一,並且更新變量的分數值為該條數據的分數,依次比較

如下圖結果:

  

跟第一條sql的結果相對比你會發現,分數相同的排名也相同,並且最后一名的名次由第9名變成了第7名;

如果你需要分數相同的排名也相同,但是后面的排名不能受到分數相同排名相同而不占位的影響,也就是哪怕你排名相同,你也占了這個位置(比如:1,2,2,4,5,5,7....這種形式的,雖然排名有相同,但是你占位了,后續的排名根據占位來排)

 

三、sql2{只要數據有相同的排名就一樣,但是相同排名也占位,排名依次排序(1,2,2,4,5,5,7.....)}  

   此時需呀再增加一個變量,來記錄排序的號碼(自增)

復制代碼
SELECT
    obj_new.user_id,
    obj_new.score,
    obj_new.rownum
FROM
    (
        SELECT
            obj.user_id,
            obj.score,
            @rownum := @rownum + 1 AS num_tmp,
            @incrnum := CASE
        WHEN @rowtotal = obj.score THEN
            @incrnum
        WHEN @rowtotal := obj.score THEN
            @rownum
        END AS rownum
        FROM
            (
                SELECT
                    user_id,
                    score
                FROM
                    `sql_rank`
                ORDER BY
                    score DESC
            ) AS obj,
            (
                SELECT
                    @rownum := 0 ,@rowtotal := NULL ,@incrnum := 0
            ) r
    ) AS obj_new
復制代碼

上面sql執行的結果如下:

  

  結果集中分數相同的,排名相同,同時它也占據了那個位置,中間的一個數據過程本人截圖了,請往下看(跟上圖做對比你就明白了):

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM