旅游網(wǎng)站建設(shè)解決方案競價托管代運營多少錢
背景
我們這里有個需求,對存量用戶的余額做排行處理,這個實現(xiàn)方式很多,這邊介紹的是,通過Mysql
直接實現(xiàn),將排名也直接返回出來。
我知道大家在網(wǎng)上能找到一大把這種實例,我在這里可不是【重復(fù)造輪子】。我是這么想的,通過剖析的方式讓大家理解這么寫的原理,以及用到了什么知識點。
Sql實例剖析(普通排行)
業(yè)務(wù)需求:獲取系統(tǒng)中,用戶余額的排行榜。相同余額排名先后順序無所謂
sql語句如下:
select tmp.*,(@r:=@r+1) as rank from
(
SELECTuu.phone_number,uw.balance_type,uw.wallet_balance
FROMus_wallet uw
INNER JOIN us_user uu ON uw.user_id = uu.user_id
order by uw.wallet_balance desc
) tmp,(select @r:=0) r;
說明:我想上面的表us_user
跟us_wallet
以及他們的字段就不用我多說了吧,這是我系統(tǒng)的業(yè)務(wù),你們也不用關(guān)心我的表跟字段是如何設(shè)計的,通過表名跟字段名都能理解了
知識點剖析:
這里我認(rèn)為有4個知識點,并且有2個是比較陌生的需要給大家說說。
(select @r:=0) r
:select是向mysql拿數(shù)據(jù);@r:=0
代表向mysql定義一個變量,初始化值為0
;外層的r
是定義別名select * from (...省略...) tmp,(select @r:=0) r
:這里的關(guān)鍵點是兩個表tmp
跟r
之間,使用逗號,
是什么意思呢?我們可以把這個叫做【逗號連接符】,等同于inner join
運算。那inner join
大家應(yīng)該知道啥意思吧?就是做【笛卡爾積】?!镜芽柗e】的意思如下:- 假設(shè)A={a, b},B={1, 2, 3}。那么對A跟B做【笛卡爾積】得到的結(jié)果是:A ? B = {(a, 1), (a, 2), (a,3), (b, 1), (b, 2), (b, 3)}。 以上是數(shù)學(xué)表示方式
- 數(shù)據(jù)庫表中解釋:左邊表的記錄 ? 右邊表的記錄
- 既然是等同于
inner join
,那inner join
的on
怎么體現(xiàn)出來?首先,inner join
其實可以省略on
的,相當(dāng)于對左右兩張表做全乘積,如果是大表的話就完犢子了!加上on
是做條件篩選而已;其次,【逗號連接符】也可以使用where
來做條件篩選的,就這么簡單而已 (@r:=@r+1)
:既然知道@r
是變量來的,這個我想大家都知道啥意思吧?就是每調(diào)用@r
一次就對@r
做一次累加咯
Sql實例剖析(并列排行)
這個算是對我上一個實例業(yè)務(wù)的補(bǔ)充,我也是在網(wǎng)上看文章偶然學(xué)習(xí)到的。我們前面的業(yè)務(wù)有一個條件是:相同余額排名先后順序無所謂。如果需求改成:相同余額排名并列,那該如何寫呢?哈哈,其實也不難,我們上面不是已經(jīng)學(xué)習(xí)了【如何向mysql新增一個變量】嘛,新增一個變量存上一次的余額不就行了嗎skr
sql如下:
SELECTtmp.*, IF(@last = tmp.wallet_balance, @r, @r := @r+1) AS rank,@last := tmp.wallet_balance AS last
FROM(SELECTuu.phone_number,uw.balance_type,uw.wallet_balanceFROMus_wallet uwINNER JOIN us_user uu ON uw.user_id = uu.user_idORDER BYuw.wallet_balance DESC) tmp,(SELECT @r := 0, @last := 0) r;
知識點剖析:
IF(expr1, expr2, expr3)
:這里用了一個跟之前不一樣的函數(shù),使用IF
函數(shù)來決定排名@r
的操作@last := tmp.wallet_balance AS last
:使用這樣的方式來記錄上一次余額的情況