日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務,提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

經(jīng)常寫SQL腳本的朋友,對查詢的多樣化要求可能會經(jīng)常頭疼。數(shù)據(jù)庫SQL的語法是固定的、但應用要求卻是千差萬別的。依靠我們所掌握的知識,大部分的查詢需求我們還是有辦法的解決的,但總有那么一些要求,把我們搞的非常被動。

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

今天我們就談一個會讓我們頭疼的問題:如何對查詢的結果進行排名。沒錯,是排名,不是排序,跟Order By有點關系,但可以認為是另一個問題。排名函數(shù)不但可以實現(xiàn)排序,還能夠生成排序的排名序列

演示數(shù)據(jù)準備

今天我們就以SQL Server為例,結合四大排名函數(shù),詳細講解一下如何使用四大排名函數(shù)實現(xiàn)查詢結果的排名。MySQL也有類似的排名函數(shù),使用方法與SQL Server大同小異

為了演示需要,我們需要先創(chuàng)建一個表變量作為銷售表,記錄不同區(qū)域、城市、年月的銷售金額,然后再對表中的數(shù)據(jù)進行排名處理。演示數(shù)據(jù)創(chuàng)建腳本如下:

declare @sale table(
 FName nvarchar(50),
 FDistrict nvarchar(50),
 FYear smallint,
 FMonth smallint,
 FAmount decimal(28,10)
);
insert into @sale
values
('張三','北京',2019,4,20000),
('張三','深圳',2019,4,40000),
('李四','北京',2019,4,30000),
('李四','深圳',2019,4,40000),
('王二','北京',2019,4,70000),
('王二','深圳',2019,4,60000),
('馬六','北京',2019,4,80000),
('馬六','深圳',2019,4,70000);

運行結果請參考下圖:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

有了演示數(shù)據(jù),我們就把四個排名函數(shù)的應用和區(qū)別挨個理一理。

ROW_NUMBER,簡單方便又強大

row_number是最常用、最簡單的排名函數(shù),其語法格式如下:

row_number() over(order by field列表 asc|desc)

語法格式看上去有點怪怪的,前半截row_number()是排名函數(shù),緊接其后的over子句則是指定排序的規(guī)則。其它三個排名函數(shù)也有over子句,用途和語法也是一樣的。整個函數(shù)作為一個整體,其返回值就是排名序列號,序列號從1開始依次累加。

比如我們要按照銷售金額進行排名,語法格式如下:

select ROW_NUMBER() over(order by FAmount desc) as FRank,* from @sale;

運行效果參考下圖:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

通過上圖的查詢結果可以看出,F(xiàn)Rank字段就是返回的排名字段。根據(jù)over子句,可以定義任何自己需要的排名規(guī)則。

如果您認為row_number函數(shù)只是能實現(xiàn)如此排名,那您就想的太簡單了。row_number函數(shù)還有一個很重要的擴展用途,可以實現(xiàn)查詢分頁,我們舉一個例子來說明如何使用row_number實現(xiàn)查詢分頁。

為了使演示效果更明顯,我們使用公用表表達式返回排名序列值和數(shù)據(jù),根據(jù)要求的每頁行數(shù)和第幾頁,通過where子句限定排名序列的起點和終點。

declare @pagesize int =4;--每頁記錄數(shù)
declare @pagenum int =1;--第幾頁
with cte as
(
 select row_number() over(order by FAmount desc) as FRank,*
 from @sale
)
select * from cte
where FRank between 
 @pagesize*(@pagenum-1)+1 
 and 
 @pagenum*@pagesize;

運行效果如下圖所示:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

這種寫法基本是通用的,您可以比葫蘆畫瓢稍加改造,就可以用在您的分頁腳本中。

如果在查詢中使用order by子句,要注意order by子句最好與排名中over子句的order by一致,如果不一致,可能導致返回排名序列是不連續(xù)的,但這并不影響數(shù)據(jù)頁的正確性。

還有一種可以實現(xiàn)分頁寫法,使用offset進行分頁,這里我就不再贅述了。如果您想要更進一步了解分頁語法,可以參考我之前寫過的文章《如何在SQLServer查詢中實現(xiàn)高效分頁》。

RANK,相同值共用排名值,跳著排

RANK函數(shù)與ROW_NUMBER函數(shù)的語法和效果類似,最大的區(qū)別在于,如果碰到相同的字段值,會使用相同的排名序列值,后續(xù)的序列值則會跳過共用序列值。

其語法格式如下:

rank() over(order by field列表 asc|desc)

下面我們就實戰(zhàn)一下:

select RANK() over(order by FAmount desc) as FRank,* from @sale;

運行效果如下圖所示:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

我們從上圖可以很明顯看出來,第2、3條記錄因值相同,使用了相同的序列值“2”,到了第四條,排名序列值直接使用了“4”而跳過了“3”。

DENSE_RANK,相同值共用排名值,接著排

DENSE_RANK函數(shù)與RANK函數(shù)的語法和效果類似,區(qū)別就像函數(shù)名稱中的DENSE(緊密的)含義一樣,如果碰到相同的字段值,雖然都會使用相同的排名序列值,但序列值是連續(xù)的。

其語法格式如下:

dense_rank() over(order by field列表 asc|desc)

下面我們就實戰(zhàn)一下:

select DENSE_RANK() over(order by FAmount desc) as FRank,* from @sale;

運行效果如下圖所示:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

可以看出RANK和DENSE_RANK確實有共同點,但也有區(qū)別。RANK排名值如果碰到相同字段值,則會使用相同的排名值,后續(xù)會跳過斷開使用新的排名值;DENSE_RANK碰到相同字段值同樣使用相同的排名值,但是接著排下來,不會斷開

NTILE,根據(jù)約定分組

NTILE函數(shù)的語法和用途上面三個明顯不同,其功能主要用來實現(xiàn)對記錄進行分組。根據(jù)NTILE約定分組的組數(shù),將查詢結果按照over子句的排序標準進行分組,分組組號按照序列排列,同一個組使用同一個組號。

其語法格式如下:

ntile(組數(shù)) over(order by field列表 asc|desc)

如果指定的組數(shù)剛好實現(xiàn)均分,則每一組的記錄數(shù)是相同的,比如我們將8條記錄分成四組,則會有四個組,組號分別是1、2、3、4,每一組都會有兩個記錄,舉例如下:

select NTILE(4) over(order by FAmount desc) as FRank,* from @sale;

運行效果如下:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

如果分成五組,明顯無法均分,那如何分呢?

當然是有一種邏輯存在的。這種邏輯可以這樣理解,從第一組開始,使用總記錄數(shù)除以組數(shù),獲取等于或最大于相除結果的最小整數(shù),作為第一組的記錄條數(shù);剩余的記錄條數(shù)按照相同算法依次類推。通俗來講,NTITLE在優(yōu)先配足靠前的分組的記錄數(shù)的前提下,盡量進行均分。

下面我們我實戰(zhàn)將以上記錄分成五組的執(zhí)行情況:

select NTILE(5) over(order by FAmount desc) as FRank,* from @sale;

運行效果如下:

善用SQL排名函數(shù),讓您的查詢飛的更精彩

 

從上圖可以看出,記錄條數(shù)是8條,分成5組,我們用8除以5,最接近且大于等于的整數(shù)是2,第一組占用了兩條記錄,這時候還剩余6條記錄分4組;依次類推,6除以4,最接近且大于等于的整數(shù)是2,第二組還是2條記錄;此時剩余4條記錄要分3組,4除以3,最接近且大于等于的整數(shù)還是2;再往下,剩余兩條分兩組,這時候就剛好均分了。

需要明確的是,NTILE也可用來分頁,但因分組邏輯的原因,效果就不如ROW_NUMBER理想了。


通過上述分析,我們對排名函數(shù)就有了充分的認識,您大可根據(jù)需要使用。希望對您有所幫助!

分享到:
標簽:SQL
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定