【mysql 】mysql 獲取排列序號

在進入正題以前先來了解一個mysql中的小知識點:mysql

①   := 與 = 的區別sql

:=   賦值的意思。在set update select 中表示賦值的意思,用的比較少通常都用=,可是在用變量實現行號時(好比本文標題獲取排列序號),必定要用:=。函數

 =   等於的意思,只有當set 和 update時,和:=的意思是同樣的,表示賦值,其他狀況都是等於的意思。學習

② 用戶變量 @編碼

@rank 是對一個叫rank的參數進行賦值。對用戶變量賦值有兩種方式,一種直接用"="另外一種用":="。其區別在於使用set命令對用戶變量賦值時,兩種方式均可以使用;當使用select語句對用戶變量進行賦值時,只能使用「:=」方式,由於在select語句中,「=」被看作是比較操做符。.net

好了,如今進入正題。日誌

一、根據某字段按序排列並獲取排序號。blog

先寫一個小例子:排序

SELECT a.*,@rank:=@rank + 1 AS rank_no
FROM (
SELECT *
FROM `logs`
WHERE log_created> "2017-09-01"
ORDER BY count DESC
     ) a, (SELECT @rank:= 0) b
這個sql的做用是將日誌建立時間在2017.09.01以前的日誌按訪問量進行倒序排序,並返回序號。(當訪問量相同的時候,按正常順序,繼續排序)。變量

運行結果以下:

 

select @rank:= 0 或者 set @rank=0;
這句話其實就是將rank賦值0,從零開始加1編號,上面兩種寫法均可以。

用set的那種方法我也列出來一下,

set @rank= 0;
SELECT a.log_id,a.log_created,a.count,@rank:=@rank + 1 AS rank_no
FROM (
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a;
因此,獲取排序序號仍是很簡單的,基本上都是固定的方式,裏面一層select是正常的sql排序的語句,外面一層是對查到的已排好序的數據列進行rank自增的操做,因此一開始@rank:=0。

其中須要注意的一點是,當排名相同時,想讓序號也同樣該怎麼辦,好比上面的查詢結果id爲1707101100和1711131423的訪問次數都是3,上面的sql是將他們按序繼續編號的,要是想編號相同能夠這樣解決:

二、根據某字段按序排列獲取排序號,且當該字段的值存在多個相同的記錄時,則相同值排序號相同。

SET @rank = 0 ,@rowtotal := NULL;
SELECT
a.log_id, a.log_created, a.count,
CASE
WHEN @rowtotal = a.count THEN
@rank
WHEN @rowtotal := a.count THEN
@rank := @rank + 1
END AS rank_no
FROM
(
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a
運行結果:

 

從上面的sql語句能夠看出多了一句case函數,(rowtotal表示count)根據狀況對rank進行賦值,當rowtotal等於count時,序號就是rank,當rowtotal正常賦值時,言下之意就是不等於,可是又不能用!= ,(其實這樣說也不許確,我也不知道該怎麼表達,有知道的人博友能夠幫忙補充一下~~~),這樣就實現了相同記錄編號相同的目的,同時其他記錄繼續編號。

三、根據某字段按序排列獲取排序號,且當該字段的值存在多個相同的記錄時,則相同值的記錄的排序號相同,而且下一組值的排序號爲上一組內記錄數+上一個排序號。

一樣先看代碼:

SET @rank = 0 ,@rowtotal := NULL ,@rowtotal1 = NULL ,@sart := 0;
SELECT a.log_id, a.log_created, a.count,
CASE
WHEN @rowtotal = a.count THEN @rank
WHEN @rowtotal := a.count THEN @rank := @rank + 1 + @sart
END AS rank_no,
CASE
WHEN @rowtotal1 = a.count THEN @sart := @sart + 1
WHEN @rowtotal1 := a.count THEN @sart := 0
END AS sart
FROM
(
SELECT *
FROM `logs`
WHERE log_update > "2017-09-01"
ORDER BY count DESC
) a

運行結果:

 

上面的sql裏又增長了一個參數sart,表示當前每次相同的個數,(同時還增長了rowtotal1,用於區別以前的roetotal,由於在這段sql中rowtotal在運行期間已被屢次賦值,不適合作sart的比較參數)下一組記錄,將在以前的排名上加上此參數就表示,下一組記錄的排序編碼。爲了再次驗證sql準確性,再看一組運行結果,(調整日誌建立時間爲log_update > "2016-06-20" and log_update < "2017-03-01"),

 

好了,這三種經常使用的獲取排列序號的sql寫好了,供你們參考一下,如果有不正確的地方還望你們指出,互相學習。


2018/04/19錯誤糾正:

上面的sql有個問題就是當數據是0的時候,沒有進行特殊處理這個時候獲得的rank_no是一個null值,排序就會出問題,下面針對第三種狀況作一下糾正其他的相似:

SET @rank = 0 ,@rowtotal := NULL ,@rowtotal1 = NULL ,@sart := 0;SELECT a.log_id, a.log_created, a.count, CASE WHEN @rowtotal = a.count THEN @rank WHEN @rowtotal := a.count THEN @rank := @rank + 1 + @sart WHEN @rowtotal = 0 THEN @rank := @rank +1 +@sart END AS rank_no, CASE WHEN @rowtotal1 = a.count THEN @sart := @sart + 1 WHEN @rowtotal1 := a.count THEN @sart := 0 WHEN @rowtotal1 =0 THEN @sart := 0 END AS sart FROM ( SELECT * FROM `logs` WHERE log_update > "2017-09-01" ORDER BY count DESC ) a上面的黑體字就是修正後的處理sql。————————————————版權聲明:本文爲CSDN博主「crainnogao」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/gao763024185/article/details/79638052

相關文章
相關標籤/搜索