日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

sql 除以_不可思议的SQL排名函数,被您无视了么?

發(fā)布時間:2023/12/15 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 sql 除以_不可思议的SQL排名函数,被您无视了么? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

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

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

演示數(shù)據(jù)準(zhǔn)備

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

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

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

運(yùn)行結(jié)果請參考下圖:

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

ROW_NUMBER,簡單方便又強(qiáng)大

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

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

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

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

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

運(yùn)行效果參考下圖:

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

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

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

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 ctewhere FRank between @pagesize*(@pagenum-1)+1 and @pagenum*@pagesize;

運(yùn)行效果如下圖所示:

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

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

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

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

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

其語法格式如下:

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

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

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

運(yùn)行效果如下圖所示:

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

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

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

其語法格式如下:

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

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

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

運(yùn)行效果如下圖所示:

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

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

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

其語法格式如下:

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

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

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

運(yùn)行效果如下:

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

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

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

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

運(yùn)行效果如下:

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

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


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

總結(jié)

以上是生活随笔為你收集整理的sql 除以_不可思议的SQL排名函数,被您无视了么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。