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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL点滴20—T-SQL中的排名函数

發布時間:2025/3/20 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL点滴20—T-SQL中的排名函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

提到排名函數我們首先可能想到的是order by,這個是排序,不是排名,排名需要在前面加個名次序號的,order by是沒有這個功能的。還可能會想到identity(1,1),它也給了一個序號,但是不能保證給出的序號是連續升序的。除非能夠保證所有的Insert語句都能夠正確成功地完成,并且沒有刪除操作,實際的使用中大多數的表都不能保證這樣。

好在SQL Server中提供了一些排名函數來輔助實現這些功能。排名函數按照需要的順序對數據進行排名,并提供一個值對數據。下面來了解一下這些排序函數功能。

  

?

ROW_NUMBER

?

ROW_NUMBER函數允許以上升,連續的順序給每一行數據一個序號,注意ROW_NUMBER()后面一定要跟著over子句。來看語句:

1use AdventureWorks
2select
3ROW_NUMBER() over(order by LastName) as RowNum,
4FirstName+' '+ LastName as FullName
5from HumanResources.vEmployee
6where JobTitle='Production Technician - WC60'

這個語句對符合條件(JobTitle='Production Technician - WC60')的LastName按照升序排列,并加上排序的序號,這個序號是連續上升的。結果如下圖1是部分結果。

圖1

我們可以看到第一個人的LastName是Abercrombie,第二個人的LastName是Adams,以次類推。

  

?

PARTITION

?

如果我們想再細分一下,在一個小的分組范圍內排序該怎么辦呢?就是說讓LastName以‘A’開頭的作為第一組,在這個組內進行排序。以‘B’開頭的作為第二組,在這個組內排序。以‘C’開頭的作為第三組,在這個組內進行排序,如此等等。這里有一個很簡單的實際例子,假如上面這些人都來參加同一場馬拉松比賽,其中有男子組,女子組,男子殘疾組,女子殘疾組,60歲以上組等等。不管參賽者以第幾位觸線,名次都以他們的小組為基準。

可以通過PARTITION BY選項來重新排序,給數據分區或者數據區域唯一的遞增序號。來看下面的語句:

[注] partition n. 劃分,分開;[數] 分割;隔墻;隔離物;vt. [數] 分割;分隔;區分

1select
2ROW_NUMBER() over(PARTITION by substring(LastName,1,1) order by LastName) as RowNum,
3FirstName+' '+ LastName as FullName
4from HumanResources.vEmployee
5where JobTitle='Production Technician - WC60'

這里模擬上面的情況,首先以Last Name的第一個字母作為分組,然后以第二個字母以后的字母來分組排序。來看看結果,如圖2



圖2

?

假設LastName以‘A’開頭的是男子組,這個組有共有三個人,Kim Abercrombie是冠軍,Jay Adams是亞軍,Nancy Anderson是季軍。假設LastName以‘B’開頭的是女子組,這個組只有一個人Bryan Baker,無論如何她都是冠軍。等等如此類推。這樣一眼就能看出他們的小組名次了。

這里你可能會覺得使用order by一樣可以得到這樣類似的結果。如下代碼:

1 select
2 FirstName+' '+ LastName as FullName
3 from HumanResources.vEmployee
4 where JobTitle='Production Technician - WC60'
5 order by substring(LastName,1,1) ,LastName

這個把order by放在最后,排序放在最后,首先按照LastName的首字母排序,再按照剩整個LastName排序,結果如下圖3



圖3

結果和上面大致相同,可是少了前面的名次序號。于是我又對她進行了修改,代碼如下:

1select
2ROW_NUMBER() over(order by substring(LastName,1,1),LastName) as RowNum,
3FirstName+' '+ LastName as FullName
4from HumanResources.vEmployee
5where JobTitle='Production Technician - WC60' 這個和上面的類似,在排名函數中使用order by,并且是按照多個字段排序。來看看結果如圖4 ?



圖4

排序沒有錯誤,是我們想要的分組排序,但是前面的名次沒有分組區分,和圖1沒有什么差別??梢妶D3和圖4的做法完全是多余,純屬臆造,其實只要order by LastName都能得到正確的排序,只有partition by才是正解。通過上面的例子也可以對排序,排名這二者之間的區別有一個認識,他們雖然有相似之處,但是排名始終會產生一個名次序號,排序只要得到正確的順序就好。

?    

RANK

?

還是拿馬拉松比賽來說事,如果有同時撞線的情況發生應該怎么計名次呢?例如A第一個撞線,B和C同時第二個撞線,D第三個撞線,如果我們想把D的名次計為第4名應該怎么處理呢?就是說不計順序名次,只計人數。這時就可以使用RANK函數了。

[注] rank n. 等級;隊列;排;軍銜vt. 排列;把…分等vi. 列隊;列為

在order by子句中定義的列上,如果返回一行數據與另一行具有相同的值,rank函數將給這些行賦予相同的排名數值。在排名的過程中,保持一個內部計數值,當值有所改變時,排名序號將有一個跳躍。

來看下面的語句:

1select
2ROW_NUMBER() over(order by Department) as RowNum,
3RANK() over(order by Department) as Ranking,
4FirstName+' '+ LastName as FullName,
5Department
6from HumanResources.vEmployeeDepartment
7order by RowNum

rank()函數右面也要跟上一個over子句。為了看到效果我們以Department作為排序字段,可以看到RowNum作為升序連續排名,Ranking作為計同排名,當Department的值相同時,Ranking中的值保持不變,當Ranking中的值發生變化時,Ranking列中的值將跳躍到正確的排名數值。來看結果:



圖5

從這個結果中我們可以說這次馬拉松賽跑的排名是:Tengiz Kharatishvili,Zainal Arifin,Sean Chai,Karen Berge,Chris Norred并列第1,Michael Sullivan,Sharon Salavaria,Roberto Tamburello,Gail Erickson,Jossef Goldberg并列第6,如此等等。



?

DENSE_RANK

?

在上面的例子中,A第一個撞線,B和C同時第二個撞線,D第三個撞線,如果我們想把B和C的名次計位第2名,D的名次計為第3名應該怎么處理呢?就是說考慮并列名次。這里使用DENSE_RANK函數,來看下面的代碼。?

?

1select
2ROW_NUMBER() over(order by Department) as RowNum,
3DENSE_RANK() over(order by Department) as Ranking,
4FirstName+' '+ LastName as FullName,
5Department
6from HumanResources.vEmployeeDepartment
7order by RowNum

?結果如下:



圖6

?

按照這個結果,我們可以說這次馬拉松賽跑的排名是:Tengiz KharatishviliZainal ArifinSean ChaiKaren BergeChris Norred并列第1Michael SullivanSharon SalavariaRoberto TamburelloGail EricksonJossef GoldbergTerri Duffy并列第2,等等如此。

?

NTILE

?

在開始這個之前,先來一段小插曲。梭羅是鉛筆的發明者,不過他沒有申請專利。據說他天賦異稟,在父親的鉛筆廠里面打包鉛筆的時候,從一堆鉛筆里面抓取一把,每次都能精確地抓到一打12支。他在森林中目測兩顆樹之間的距離,和護林員用卷尺測量的結果相差無幾。現在如果我們想從一張表中抓取多比數據,每一筆都是相同的數目,并且標明第幾組該怎么辦呢?NTILE函數提供了這個功能,他能。來看代碼:

1 select
2 NTILE(30) over(order by Department) as NTiles,
3 FirstName+' '+ LastName as FullName,
4 Department
5 from HumanResources.vEmployeeDepartment

現在我們要抓取30個組的數據,并保證盡可能的保證每組數目相同。結果如下,



圖7

這個視圖中共290條數據,290/30=9.7約等于10,所以每組10條數據,如圖每一條數據都有一個組號。這個結果要比索羅精確。

總結

以上是生活随笔為你收集整理的SQL点滴20—T-SQL中的排名函数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 欧美三级免费 | 亚洲精选一区二区三区 | 日韩一区二区三区网站 | 亚洲高清在线免费观看 | 国模一区二区 | 中国毛片网 | 影音先锋亚洲天堂 | 农民人伦一区二区三区 | 日日操天天操 | 久久久精品91 | 精品国产一区二区三区在线观看 | av网站有哪些 | 精品午夜一区二区三区在线观看 | 国产美女福利视频 | 嫩操影院 | 深夜视频在线看 | 欧美图片一区二区 | 91狠狠综合| 波多野结衣视频免费看 | 国产色网站 | 黑人操日本女人 | 欧美精品一区二区三区四区 | 日韩精品极品视频 | 日韩爱爱视频 | 久久精品色妇熟妇丰满人妻 | 午夜爽爽爽视频 | 中文在线不卡 | 国产精品无码乱伦 | 在线观看视频一区二区三区 | 91毛片网站 | 春闺艳妇(h)高h产乳 | 亚洲av无码专区首页 | 调教撅屁股啪调教打臀缝av | 精品国偷自产在线 | 国产精品高潮呻吟久久 | 亚洲一区二区在线免费 | 蜜桃久久久久久 | 在线色av| 制服丝袜先锋影音 | 日韩视频在线播放 | h官场少妇第三部分 | 久久作爱 | 亚洲熟妇av日韩熟妇在线 | 97超碰人人澡人人爱学生 | 九九精品在线观看视频 | 午夜小影院 | 农村少妇久久久久久久 | 日本成人动漫在线观看 | 亚洲天堂网址 | 国产一区二区三区三州 | 黑帮大佬和我的三百六十五天 | 一本色道久久亚洲综合精品蜜桃 | 精品久操 | 亚洲国产日韩在线观看 | 色黄大色黄女片免费中国 | 久久久九九九热 | 天天综合在线观看 | 欧美人体一区二区三区 | 国产中文字幕二区 | 91丨porny在线 | 亚洲无码精品国产 | 欧美成人三级在线视频 | 人成在线免费视频 | 日日操狠狠干 | 污视频网站在线观看 | 日韩精品一区二区三区视频 | 国产v亚洲v天堂无码 | 日本超碰 | 亚洲综合二区 | 牛牛精品一区 | 快播日韩| 秋霞在线一区 | 视频免费在线 | 亚洲九九爱 | 台湾性生生活1 | 日本中文字幕观看 | 精品国产乱码久久久久久闺蜜 | 大桥未久恸哭の女教师 | 国产一区二区三区视频在线 | 亚洲码欧美码一区二区三区 | 日本aⅴ视频 | 欧美精品一区二区性色a+v | 殴美一级片 | 第一色综合 | 天天舔天天射天天干 | 天天躁日日躁狠狠很躁 | 性色tv| 亚洲精品一区三区三区在线观看 | 国产精品二区三区 | 国产原创剧情av | 欧美人与牲动xxxx | 欧美色综合网 | 日韩最新中文字幕 | 美女张开腿让男人操 | 日韩一区二区免费视频 | 国产又爽又黄免费视频 | 禁片天堂| 2一3sex性hd| 欧美xxxx日本和非洲 |