SQL實現統計排名

2021-10-20 19:31:02 字數 4696 閱讀 3215

在某些應用場景中,我們經常會遇到一些排名的問題,比如按成績或年齡排名。排名也有多種排名方式,如直接排名、分組排名,排名有間隔或排名無間隔等等,這篇文章將總結幾種mysql中常見的排名問題。

create

table scores_tb (

id int

auto_increment

primary

key,

xuehao int

notnull

, score int

notnull

)engine

=innodb

default

charset

=utf8;

insert

into scores_tb (xuehao,score)

values

(1001,89

),(1002,99

),(1003,96

),(1004,96

),(1005,92

),(1006,90

),(1007,90

),(1008,94

);# 檢視下插入的資料

mysql>

select

*from scores_tb;

+----+--------+-------+

| id | xuehao | score |

+----+--------+-------+|1

|1001|89

||2|

1002|99

||3|

1003|96

||4|

1004|96

||5|

1005|92

||6|

1006|90

||7|

1007|90

||8|

1008|94

|+----+--------+-------+

按分數高低直接排名,從1開始,往下排,類似於row number。下面我們給出查詢語句及排名結果。

# 查詢語句

select xuehao, score,

@currank :=

@currank+1

as rank

from scores_tb,

(select

@currank :=

0) r

order

by score desc

;# 排序結果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

|1002|99

|1||

1003|96

|2||

1004|96

|3||

1008|94

|4||

1005|92

|5||

1006|90

|6||

1007|90

|7||

1001|89

|8|+

--------+-------+------+

# 查詢語句

select xuehao, score,

case

when

@prevrank

= score then

@currank

when

@prevrank := score then

@currank :=

@currank+1

endas rank

from scores_tb,

(select

@currank :=0,

@prevrank :=

null

) rorder

by score desc

;# 排名結果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

|1002|99

|1||

1003|96

|2||

1004|96

|2||

1008|94

|3||

1005|92

|4||

1006|90

|5||

1007|90

|5||

1001|89

|6|+

--------+-------+------+

另外一種排名方式是相同的值排名相同,相同值的下乙個名次應該是跳躍整數值,即排名有間隔。

# 查詢語句

select xuehao, score, rank from

(select xuehao, score,

@currank :=if(

@prevrank

= score,

@currank

,@incrank

)as rank,

@incrank :=

@incrank+1

,@prevrank := score

from scores_tb,

(select

@currank :=0,

@prevrank :=

null

,@incrank :=

1) r

order

by score desc

) s;

# 排名結果

+--------+-------+------+

| xuehao | score | rank |

+--------+-------+------+

|1002|99

|1||

1003|96

|2||

1004|96

|2||

1008|94

|4||

1005|92

|5||

1006|90

|6||

1007|90

|6||

1001|89

|8|+

--------+-------+------+

上面介紹了三種排名方式,實現起來還是比較複雜的。好在mysql8.0增加了視窗函式,使用內建函式可以輕鬆實現上述排名。

mysql8.0中可以利用 row_number(),dense_rank(),rank() 三個視窗函式實現上述三種排名,需要注意的一點是as後的別名,千萬不要與前面的函式名重名,否則會報錯,下面給出這三種函式實現排名的案例:

# 三條語句對於上面三種排名

select xuehao,score, row_number(

)over

(order

by score desc

)as row_r from scores_tb;

select xuehao,score, dense_rank(

)over

(order

by score desc

)as dense_r from scores_tb;

select xuehao,score, rank(

)over

(order

by score desc

)as r from scores_tb;

# 一條語句也可以查詢出不同排名

select xuehao,score,

row_number(

)over w as

'row_r'

, dense_rank(

)over w as

'dense_r'

, rank(

)over w as

'r'from

`scores_tb`

window w as

(order

by`score`

desc);

# 排名結果

+--------+-------+-------+---------+---+

| xuehao | score | row_r | dense_r | r |

+--------+-------+-------+---------+---+

|1002|99

|1|1

|1||

1003|96

|2|2

|2||

1004|96

|3|2

|2||

1008|94

|4|3

|4||

1005|92

|5|4

|5||

1006|90

|6|5

|6||

1007|90

|7|5

|6||

1001|89

|8|6

|8|+

--------+-------+-------+---------+---+

本文給出三種不同場景下實現統計排名的sql,可以根據不同業務需求選取合適的排名方案。對比mysql8.0,發現利用視窗函式可以更輕鬆實現排名,其實業務需求遠遠比我們舉的示例要複雜許多,用sql實現此類業務需求還是需要慢慢積累的。

教你用SQL實現統計排名

前言 在某些應用場景中,我們經常會遇到一些排名的問題,比如按成績或年齡排名。排名也有多種排名方式,如直接排名 分組排名,排名有間隔或排名無間隔等等,這篇文章將總結幾種mysql中常見的排名問題。建立測試表 create table scores tb id int auto increment pr...

SQL成績統計分析 排名問題

select from studentscore select row number over order by studentscore desc,id desc number,from studentscore 下面介紹下在sql成績統計分析中遇到的一些小問題,首先介紹下成績分析中經常遇到的問題...

Sql排名和分組排名

在很多時候,都有排名這個功能,比如排行榜,並且還需要分頁的功能,一般可以再select的時候按照某一字段 oorder by xx desc,這樣limit 查詢就可以得到排名資訊,但是有時候是需要多表連線,或者是有乙個隨機檢視,在頁面上並不是按照排名公升降序。這個時候就需要用sql來實現排名。先準...