国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

Sql中排名函數有哪些

發(fā)布時(shí)間:2021-09-27 17:43 來(lái)源:億速云 閱讀:0 作者:小新 欄目: Mysql 歡迎投稿:712375056

這篇文章主要介紹了Sql中排名函數有哪些,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著(zhù)大家一起了解一下。

排名函數是Sql Server2005新增的功能,下面簡(jiǎn)單介紹一下他們各自的用法和區別。我們新建一張Order表并添加一些初始數據方便我們查看效果。

表結構和初始數據Sql

附上表結構和初始數據圖:

  

一、ROW_NUMBER

  row_number的用途的非常廣泛,排序最好用他,一般可以用來(lái)實(shí)現web程序的分頁(yè),他會(huì )為查詢(xún)出來(lái)的每一行記錄生成一個(gè)序號,依次排序且不會(huì )重復,注意使用row_number函數時(shí)必須要用over子句選擇對某一列進(jìn)行排序才能生成序號。row_number用法實(shí)例:

select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order]

  查詢(xún)結果如下圖所示:

  

  圖中的row_num列就是row_number函數生成的序號列,其基本原理是先使用over子句中的排序語(yǔ)句對記錄進(jìn)行排序,然后按照這個(gè)順序生成序號。over子句中的order by子句與SQL語(yǔ)句中的order by子句沒(méi)有任何關(guān)系,這兩處的order by 可以完全不同,如以下sql,over子句中根據SubTime降序排列,Sql語(yǔ)句中則按TotalPrice降序排列。

select ROW_NUMBER() OVER(order by [SubTime] desc) as row_num,* from [Order] order by [TotalPrice] desc

  查詢(xún)結果如下圖所示:

  

  利用row_number可以實(shí)現web程序的分頁(yè),我們來(lái)查詢(xún)指定范圍的表數據。例:根據訂單提交時(shí)間倒序排列獲取第三至第五條數據。

with orderSection as(    select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [SubTime] desc

  查詢(xún)結果如下圖所示:

  

  注意:在使用row_number實(shí)現分頁(yè)時(shí)需要特別注意一點(diǎn),over子句中的order by 要與Sql排序記錄中的order by 保持一致,否則得到的序號可能不是連續的。下面我們寫(xiě)一個(gè)例子來(lái)證實(shí)這一點(diǎn),將上面Sql語(yǔ)句中的排序字段由SubTime改為T(mén)otalPrice。另外提一下,對于帶有子查詢(xún)和CTE的查詢(xún),子查詢(xún)和CTE查詢(xún)有序并不代表整個(gè)查詢(xún)有序,除非顯示指定了order by。

with orderSection as(    select ROW_NUMBER() OVER(order by [SubTime] desc) rownum,* from [Order])select * from [orderSection] where rownum between 3 and 5 order by [TotalPrice] desc

  查詢(xún)結果如下圖所示:

  

二、RANK

  rank函數用于返回結果集的分區內每行的排名, 行的排名是相關(guān)行之前的排名數加一。簡(jiǎn)單來(lái)說(shuō)rank函數就是對查詢(xún)出來(lái)的記錄進(jìn)行排名,與row_number函數不同的是,rank函數考慮到了over子句中排序字段值相同的情況,如果使用rank函數來(lái)生成序號,over子句中排序字段值相同的序號是一樣的,后面字段值不相同的序號將跳過(guò)相同的排名號排下一個(gè),也就是相關(guān)行之前的排名數加一,可以理解為根據當前的記錄數生成序號,后面的記錄依此類(lèi)推??赡芪颐枋龅谋容^蒼白,理解起來(lái)也比較吃力,我們直接上代碼,rank函數的使用方法與row_number函數完全相同。

select RANK() OVER(order by [UserId]) as rank,* from [Order]

  查詢(xún)結果如下圖所示:

  

  由上圖可以看出,rank函數在進(jìn)行排名時(shí),同一組的序號是一樣的,而后面的則是根據當前的記錄數依次類(lèi)推,圖中第一、二條記錄的用戶(hù)Id相同,所以他們的序號是一樣的,第三條記錄的序號則是3?! ?/p>

三、DENSE_RANK

  dense_rank函數的功能與rank函數類(lèi)似,dense_rank函數在生成序號時(shí)是連續的,而rank函數生成的序號有可能不連續。dense_rank函數出現相同排名時(shí),將不跳過(guò)相同排名號,rank值緊接上一次的rank值。在各個(gè)分組內,rank()是跳躍排序,有兩個(gè)第一名時(shí)接下來(lái)就是第四名,dense_rank()是連續排序,有兩個(gè)第一名時(shí)仍然跟著(zhù)第二名。將上面的Sql語(yǔ)句改由dense_rank函數來(lái)實(shí)現。

select DENSE_RANK() OVER(order by [UserId]) as den_rank,* from [Order]

  查詢(xún)結果如下圖所示:

  

  圖中第一、二條記錄的用戶(hù)Id相同,所以他們的序號是一樣的,第三條記錄的序號緊接上一個(gè)的序號,所以為2不為3,后面的依此類(lèi)推。

四、NTILE

  ntile函數可以對序號進(jìn)行分組處理,將有序分區中的行分發(fā)到指定數目的組中。 各個(gè)組有編號,編號從一開(kāi)始。 對于每一個(gè)行,ntile 將返回此行所屬的組的編號。這就相當于將查詢(xún)出來(lái)的記錄集放到指定長(cháng)度的數組中,每一個(gè)數組元素存放一定數量的記錄。ntile函數為每條記錄生成的序號就是這條記錄所有的數組元素的索引(從1開(kāi)始)。也可以將每一個(gè)分配記錄的數組元素稱(chēng)為“桶”。ntile函數有一個(gè)參數,用來(lái)指定桶數。下面的SQL語(yǔ)句使用ntile函數對Order表進(jìn)行了裝桶處理:

select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]

  查詢(xún)結果如下圖所示:

  

  Order表的總記錄數是6條,而上面的Sql語(yǔ)句ntile函數指定的組數是4,那么Sql Server2005是怎么來(lái)決定每一組應該分多少條記錄呢?這里我們就需要了解ntile函數的分組依據(約定)。

  ntile函數的分組依據(約定):

  1、每組的記錄數不能大于它上一組的記錄數,即編號小的桶放的記錄數不能小于編號大的桶。也就是說(shuō),第1組中的記錄數只能大于等于第2組及以后各組中的記錄數。

  2、所有組中的記錄數要么都相同,要么從某一個(gè)記錄較少的組(命名為X)開(kāi)始后面所有組的記錄數都與該組(X組)的記錄數相同。也就是說(shuō),如果有個(gè)組,前三組的記錄數都是9,而第四組的記錄數是8,那么第五組和第六組的記錄數也必須是8。

  這里對約定2進(jìn)行詳細說(shuō)明一下,以便于更好的理解。

  首先系統會(huì )去檢查能不能對所有滿(mǎn)足條件的記錄進(jìn)行平均分組,若能則直接平均分配就完成分組了;若不能,則會(huì )先分出一個(gè)組,這個(gè)組分多少條記錄呢?就是 (總記錄數/總組數)+1 條,之所以分配 (總記錄數/總組數)+1 條是因為當不能進(jìn)行平均分組時(shí),總記錄數%總組數肯定是有余的,又因為分組約定1,所以先分出去的組需要+1條。

  分完之后系統會(huì )繼續去比較余下的記錄數和未分配的組數能不能進(jìn)行平均分配,若能,則平均分配余下的記錄;若不能,則再分出去一組,這個(gè)組的記錄數也是(總記錄數/總組數)+1條。

  然后系統繼續去比較余下的記錄數和未分配的組數能不能進(jìn)行平均分配,若能,則平均分配余下的記錄;若還是不能,則再分配出去一組,繼續比較余下的......這樣一直進(jìn)行下去,直至分組完成。

  舉個(gè)例子,將51條記錄分配成5組,51%5==1不能平均分配,則先分出去一組(51/5)+1=11條記錄,然后比較余下的 51-11=40 條記錄能否平均分配給未分配的4組,能平均分配,則剩下的4組,每組各40/4=10 條記錄,分配完成,分配結果為:11,10,10,10,10,曉菜鳥(niǎo)我開(kāi)始就錯誤的以為他會(huì )分配成 11,11,11,11,7。

  根據上面的兩個(gè)約定,可以得出如下的算法:

//mod表示取余,p表示取整.if(記錄總數 mod 桶數==0)
{
  recordCount=記錄總數 p 桶數;
  //將每桶的記錄數都設為recordCount.}else{
  recordCount1=記錄總數 p 桶數+1;
  int n=1;//n表示桶中記錄數為recordCount1的最大桶數.  m=recordCount1*n;  while(((記錄總數-m) mod (桶數- n)) !=0)
  {
    n++;
    m=recordCount1*n;
  }
  recordCount2=(記錄總數-m) p (桶數-n);
  //將前n個(gè)桶的記錄數設為recordCount1.  //將n+1個(gè)至后面所有桶的記錄數設為recordCount2.}

 NTILE()函數算法實(shí)現代碼

  根據上面的算法,如果總記錄數為59,總組數為5,則 n=4 , recordCount1=12 , recordCount2=11,分組結果為 :12,12,12,12,11。

  如果總記錄數為53,總組數為5,則 n=3 , recordCount1=11 , recordCount2=10,分組結果為:11,11,11,10,10。

  就拿上面的例子來(lái)說(shuō),總記錄數為6,總組數為4,通過(guò)算法得到 n=2 , recordCount1=2 , recordCount2=1,分組結果為:2,2,1,1。

select ntile,COUNT([ID]) recordCount from (    select NTILE(4) OVER(order by [SubTime] desc) as ntile,* from [Order]) as tgroup by t.ntile

  運行Sql,分組結果如圖:

  

  比對算法與Sql Server的分組結果是一致的,說(shuō)明算法沒(méi)錯。:)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。

SQL
成全视频在线观看免费看下载| 亚洲欧美日韩自偷自拍| 国产精品点击进入在线影院高清| 免费欧洲毛片A级视频| 狠狠色综合TV久久久久久| 最近中文字幕MV免费高清动漫|