本篇文章給大家?guī)?lái)了關(guān)于SQL server的相關(guān)知識(shí),開窗函數(shù)也叫分析函數(shù)有兩類,一類是聚合開窗函數(shù),一類是排序開窗函數(shù),下面這篇文章主要給大家介紹了關(guān)于SQL中開窗函數(shù)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下。
推薦學(xué)習(xí):《SQL教程》
OVER的定義
OVER用于為行定義一個(gè)窗口,它對(duì)一組值進(jìn)行操作,不需要使用GROUP BY子句對(duì)數(shù)據(jù)進(jìn)行分組,能夠在同一行中同時(shí)返回基礎(chǔ)行的列和聚合列。
OVER的語(yǔ)法
OVER ( [ PARTITION BY column ] [ ORDER BY culumn ] )
PARTITION BY 子句進(jìn)行分組;
ORDER BY 子句進(jìn)行排序。
窗口函數(shù)OVER()指定一組行,開窗函數(shù)計(jì)算從窗口函數(shù)輸出的結(jié)果集中各行的值。
開窗函數(shù)不需要使用GROUP BY就可以對(duì)數(shù)據(jù)進(jìn)行分組,還可以同時(shí)返回基礎(chǔ)行的列和聚合列。
OVER的用法
OVER開窗函數(shù)必須與聚合函數(shù)或排序函數(shù)一起使用,聚合函數(shù)一般指SUM(),MAX(),MIN,COUNT(),AVG()等常見函數(shù)。排序函數(shù)一般指RANK(),ROW_NUMBER(),DENSE_RANK(),NTILE()等。
OVER在聚合函數(shù)中使用的示例
我們以SUM和COUNT函數(shù)作為示例來(lái)給大家演示。
--建立測(cè)試表和測(cè)試數(shù)據(jù) CREATE TABLE Employee ( ID INT PRIMARY KEY, Name VARCHAR(20), GroupName VARCHAR(20), Salary INT ) INSERT INTO Employee VALUES(1,'小明','開發(fā)部',8000), (4,'小張','開發(fā)部',7600), (5,'小白','開發(fā)部',7000), (8,'小王','財(cái)務(wù)部',5000), (9, null,'財(cái)務(wù)部',NULL), (15,'小劉','財(cái)務(wù)部',6000), (16,'小高','行政部',4500), (18,'小王','行政部',4000), (23,'小李','行政部',4500), (29,'小吳','行政部',4700);
SUM后的開窗函數(shù)
SELECT *, SUM(Salary) OVER(PARTITION BY Groupname) 每個(gè)組的總工資, SUM(Salary) OVER(PARTITION BY groupname ORDER BY ID) 每個(gè)組的累計(jì)總工資, SUM(Salary) OVER(ORDER BY ID) 累計(jì)工資, SUM(Salary) OVER() 總工資 from Employee
(提示:可以左右滑動(dòng)代碼)
結(jié)果如下:
其中開窗函數(shù)的每個(gè)含義不同,我們來(lái)具體解讀一下:
SUM(Salary) OVER (PARTITION BY Groupname)
只對(duì)PARTITION BY后面的列Groupname進(jìn)行分組,分組后求解Salary的和。
SUM(Salary) OVER (PARTITION BY Groupname ORDER BY ID)
對(duì)PARTITION BY后面的列Groupname進(jìn)行分組,然后按ORDER BY 后的ID進(jìn)行排序,然后在組內(nèi)對(duì)Salary進(jìn)行累加處理。
SUM(Salary) OVER (ORDER BY ID)
只對(duì)ORDER BY 后的ID內(nèi)容進(jìn)行排序,對(duì)排完序后的Salary進(jìn)行累加處理。
SUM(Salary) OVER ()
對(duì)Salary進(jìn)行匯總處理
COUNT后的開窗函數(shù)
SELECT *, COUNT(*) OVER(PARTITION BY Groupname ) 每個(gè)組的個(gè)數(shù), COUNT(*) OVER(PARTITION BY Groupname ORDER BY ID) 每個(gè)組的累積個(gè)數(shù), COUNT(*) OVER(ORDER BY ID) 累積個(gè)數(shù) , COUNT(*) OVER() 總個(gè)數(shù) from Employee
返回的結(jié)果如下圖:
后面的每個(gè)開窗函數(shù)就不再一一解讀了,可以對(duì)照上面SUM后的開窗函數(shù)進(jìn)行一一對(duì)照。
OVER在排序函數(shù)中使用的示例
我們對(duì)4個(gè)排序函數(shù)一一演示
--先建立測(cè)試表和測(cè)試數(shù)據(jù) WITH t AS (SELECT 1 StuID,'一班' ClassName,70 Score UNION ALL SELECT 2,'一班',85 UNION ALL SELECT 3,'一班',85 UNION ALL SELECT 4,'二班',80 UNION ALL SELECT 5,'二班',74 UNION ALL SELECT 6,'二班',80 ) SELECT * INTO Scores FROM t; SELECT * FROM Scores
ROW_NUMBER()
定義:ROW_NUMBER()函數(shù)作用就是將SELECT查詢到的數(shù)據(jù)進(jìn)行排序,每一條數(shù)據(jù)加一個(gè)序號(hào),他不能用做于學(xué)生成績(jī)的排名,一般多用于分頁(yè)查詢,比如查詢前10個(gè) 查詢10-100個(gè)學(xué)生。ROW_NUMBER()必須與ORDER BY一起使用,否則會(huì)報(bào)錯(cuò)。
對(duì)學(xué)生成績(jī)排序
SELECT *, ROW_NUMBER() OVER (PARTITION BY ClassName ORDER BY SCORE DESC) 班內(nèi)排序, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 總排序 FROM Scores;
結(jié)果如下:
這里的PARTITION BY和ORDER BY的作用與我們?cè)谏厦婵吹降木酆虾瘮?shù)的作用一樣,都是用來(lái)進(jìn)行分組和排序使用的。
此外ROW_NUMBER()函數(shù)還可以取指定順序的數(shù)據(jù)。
SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 總排序 FROM Scores ) t WHERE t.總排序=2;
結(jié)果如下:
RANK()
定義:RANK()函數(shù),顧名思義排名函數(shù),可以對(duì)某一個(gè)字段進(jìn)行排名,這里和ROW_NUMBER()有什么不一樣呢?ROW_NUMBER()是排序,當(dāng)存在相同成績(jī)的學(xué)生時(shí),ROW_NUMBER()會(huì)依次進(jìn)行排序,他們序號(hào)不相同,而Rank()則不一樣。如果出現(xiàn)相同的,他們的排名是一樣的。下面看例子:
示例
SELECT ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores; SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;
結(jié)果:
其中上圖是ROW_NUMBER()的結(jié)果,下圖是RANK()的結(jié)果。當(dāng)出現(xiàn)兩個(gè)學(xué)生成績(jī)相同是里面出現(xiàn)變化。RANK()是1-1-3-3-5-6,而ROW_NUMBER()則還是1-2-3-4-5-6,這就是RANK()和ROW_NUMBER()的區(qū)別了。
DENSE_RANK()
定義:DENSE_RANK()函數(shù)也是排名函數(shù),和RANK()功能相似,也是對(duì)字段進(jìn)行排名,那它和RANK()到底有什么不同那?特別是對(duì)于有成績(jī)相同的情況,DENSE_RANK()排名是連續(xù)的,RANK()是跳躍的排名,一般情況下用的排名函數(shù)就是RANK() 我們看例子:
示例
SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores; SELECT DENSE_RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;
結(jié)果如下:
上面是RANK()的結(jié)果,下面是DENSE_RANK()的結(jié)果
NTILE()
定義:NTILE()函數(shù)是將有序分區(qū)中的行分發(fā)到指定數(shù)目的組中,各個(gè)組有編號(hào),編號(hào)從1開始,就像我們說(shuō)的'分區(qū)'一樣 ,分為幾個(gè)區(qū),一個(gè)區(qū)會(huì)有多少個(gè)。
SELECT *,NTILE(1) OVER (ORDER BY SCORE DESC) AS 分區(qū)后排序 FROM Scores; SELECT *,NTILE(2) OVER (ORDER BY SCORE DESC) AS 分區(qū)后排序 FROM Scores; SELECT *,NTILE(3) OVER (ORDER BY SCORE DESC) AS 分區(qū)后排序 FROM Scores;
結(jié)果如下:
就是將查詢出來(lái)的記錄根據(jù)NTILE函數(shù)里的參數(shù)進(jìn)行平分分區(qū)。
總結(jié)
OVER開窗函數(shù)是我們工作中經(jīng)常要使用到的,特別是在做數(shù)據(jù)分析計(jì)算的時(shí)候,經(jīng)常要對(duì)數(shù)據(jù)進(jìn)行分組排序。上面我們額外介紹了聚合函數(shù)和排序函數(shù)的與OVER結(jié)合的使用方法,此外還有很多與OVER一起使用的函數(shù),比如LEAD函數(shù),LAG函數(shù),STRING_AGG函數(shù)等等都會(huì)使用到開窗函數(shù)OVER,其使用方法也要?jiǎng)?wù)必掌握。
推薦學(xué)習(xí):《SQL教程》
VIP推薦:共22門課程,總價(jià)3725元,開通VIP會(huì)員免費(fèi)