站長資訊網
        最全最豐富的資訊網站

        一文搞懂SQL中的開窗函數

        本篇文章給大家帶來了關于SQL server的相關知識,開窗函數也叫分析函數有兩類,一類是聚合開窗函數,一類是排序開窗函數,下面這篇文章主要給大家介紹了關于SQL中開窗函數的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下。

        一文搞懂SQL中的開窗函數

        推薦學習:《SQL教程》

        OVER的定義

        OVER用于為行定義一個窗口,它對一組值進行操作,不需要使用GROUP BY子句對數據進行分組,能夠在同一行中同時返回基礎行的列和聚合列。

        OVER的語法

        OVER ( [ PARTITION BY column ] [ ORDER BY culumn ] )

        PARTITION BY 子句進行分組;

        ORDER BY 子句進行排序。

        窗口函數OVER()指定一組行,開窗函數計算從窗口函數輸出的結果集中各行的值。

        開窗函數不需要使用GROUP BY就可以對數據進行分組,還可以同時返回基礎行的列和聚合列。

        OVER的用法

        OVER開窗函數必須與聚合函數或排序函數一起使用,聚合函數一般指SUM(),MAX(),MIN,COUNT(),AVG()等常見函數。排序函數一般指RANK(),ROW_NUMBER(),DENSE_RANK(),NTILE()等。

        OVER在聚合函數中使用的示例

        我們以SUM和COUNT函數作為示例來給大家演示。

        --建立測試表和測試數據 CREATE TABLE Employee ( ID INT  PRIMARY KEY, Name VARCHAR(20), GroupName VARCHAR(20), Salary INT ) INSERT INTO  Employee VALUES(1,'小明','開發部',8000),       (4,'小張','開發部',7600),       (5,'小白','開發部',7000),       (8,'小王','財務部',5000),       (9, null,'財務部',NULL),       (15,'小劉','財務部',6000),       (16,'小高','行政部',4500),       (18,'小王','行政部',4000),       (23,'小李','行政部',4500),       (29,'小吳','行政部',4700);

        SUM后的開窗函數

        SELECT *,      SUM(Salary) OVER(PARTITION BY Groupname) 每個組的總工資,      SUM(Salary) OVER(PARTITION BY groupname ORDER BY ID) 每個組的累計總工資,      SUM(Salary) OVER(ORDER BY ID) 累計工資,      SUM(Salary) OVER() 總工資 from Employee

        (提示:可以左右滑動代碼)

        結果如下:

        一文搞懂SQL中的開窗函數

        其中開窗函數的每個含義不同,我們來具體解讀一下:

        SUM(Salary) OVER (PARTITION BY Groupname)

        只對PARTITION BY后面的列Groupname進行分組,分組后求解Salary的和。

        SUM(Salary) OVER (PARTITION BY Groupname ORDER BY ID)

        對PARTITION BY后面的列Groupname進行分組,然后按ORDER BY 后的ID進行排序,然后在組內對Salary進行累加處理。

        SUM(Salary) OVER (ORDER BY ID)

        只對ORDER BY 后的ID內容進行排序,對排完序后的Salary進行累加處理。

        SUM(Salary) OVER ()

        對Salary進行匯總處理

        COUNT后的開窗函數

        SELECT *,        COUNT(*) OVER(PARTITION BY Groupname ) 每個組的個數,        COUNT(*) OVER(PARTITION BY Groupname ORDER BY ID) 每個組的累積個數,        COUNT(*) OVER(ORDER BY ID) 累積個數 ,        COUNT(*) OVER() 總個數 from Employee

        返回的結果如下圖:

        一文搞懂SQL中的開窗函數

        后面的每個開窗函數就不再一一解讀了,可以對照上面SUM后的開窗函數進行一一對照。

        OVER在排序函數中使用的示例

        我們對4個排序函數一一演示

        --先建立測試表和測試數據 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()函數作用就是將SELECT查詢到的數據進行排序,每一條數據加一個序號,他不能用做于學生成績的排名,一般多用于分頁查詢,比如查詢前10個 查詢10-100個學生。ROW_NUMBER()必須與ORDER BY一起使用,否則會報錯。

        對學生成績排序

        SELECT *, ROW_NUMBER() OVER (PARTITION BY ClassName ORDER BY SCORE DESC) 班內排序, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 總排序 FROM Scores;

        結果如下:

        一文搞懂SQL中的開窗函數

        這里的PARTITION BY和ORDER BY的作用與我們在上面看到的聚合函數的作用一樣,都是用來進行分組和排序使用的。

        此外ROW_NUMBER()函數還可以取指定順序的數據。

        SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 總排序 FROM Scores ) t WHERE t.總排序=2;

        結果如下:

        一文搞懂SQL中的開窗函數

        RANK()

        定義:RANK()函數,顧名思義排名函數,可以對某一個字段進行排名,這里和ROW_NUMBER()有什么不一樣呢?ROW_NUMBER()是排序,當存在相同成績的學生時,ROW_NUMBER()會依次進行排序,他們序號不相同,而Rank()則不一樣。如果出現相同的,他們的排名是一樣的。下面看例子:

        示例

        SELECT ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;   SELECT RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;

        結果:

        一文搞懂SQL中的開窗函數

        一文搞懂SQL中的開窗函數

        其中上圖是ROW_NUMBER()的結果,下圖是RANK()的結果。當出現兩個學生成績相同是里面出現變化。RANK()是1-1-3-3-5-6,而ROW_NUMBER()則還是1-2-3-4-5-6,這就是RANK()和ROW_NUMBER()的區別了。

        DENSE_RANK()

        定義:DENSE_RANK()函數也是排名函數,和RANK()功能相似,也是對字段進行排名,那它和RANK()到底有什么不同那?特別是對于有成績相同的情況,DENSE_RANK()排名是連續的,RANK()是跳躍的排名,一般情況下用的排名函數就是RANK() 我們看例子:

        示例

        SELECT  RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;   SELECT  DENSE_RANK() OVER (ORDER BY SCORE DESC) AS [RANK],* FROM Scores;

        結果如下:

        一文搞懂SQL中的開窗函數

        一文搞懂SQL中的開窗函數

        上面是RANK()的結果,下面是DENSE_RANK()的結果

        NTILE()

        定義:NTILE()函數是將有序分區中的行分發到指定數目的組中,各個組有編號,編號從1開始,就像我們說的'分區'一樣 ,分為幾個區,一個區會有多少個。

        SELECT *,NTILE(1) OVER (ORDER BY SCORE DESC) AS 分區后排序 FROM Scores; SELECT *,NTILE(2) OVER (ORDER BY SCORE DESC) AS 分區后排序 FROM Scores; SELECT *,NTILE(3) OVER (ORDER BY SCORE DESC) AS 分區后排序 FROM Scores;

        結果如下:

        一文搞懂SQL中的開窗函數

        一文搞懂SQL中的開窗函數

        一文搞懂SQL中的開窗函數

        就是將查詢出來的記錄根據NTILE函數里的參數進行平分分區。

        總結

        OVER開窗函數是我們工作中經常要使用到的,特別是在做數據分析計算的時候,經常要對數據進行分組排序。上面我們額外介紹了聚合函數和排序函數的與OVER結合的使用方法,此外還有很多與OVER一起使用的函數,比如LEAD函數,LAG函數,STRING_AGG函數等等都會使用到開窗函數OVER,其使用方法也要務必掌握。

        推薦學習:《SQL教程》

        VIP推薦:共22門課程,總價3725元,開通VIP會員免費

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 亚洲av永久无码精品网站| 国产成人精品999在线观看| 久久精品无码专区免费东京热 | 2020最新久久久视精品爱| 亚洲AV无码成人精品区天堂 | 香港aa三级久久三级老师2021国产三级精品三级在 | 日韩精品专区在线影院重磅 | 国内精品视频在线观看| 久久久久久久99精品免费观看| 久久夜色精品国产网站| 亚洲色精品88色婷婷七月丁香 | 亚洲午夜精品一级在线播放放| 国产精品视频一区二区三区不卡| 国产精品1区2区| 精品国产v无码大片在线观看| 一夲道无码人妻精品一区二区| 久久久人妻精品无码一区| 国产精品第一区第27页| 6080亚洲精品午夜福利| 久久精品国产只有精品2020| 97精品国产91久久久久久| 精品卡一卡二卡乱码高清| 日韩人妻精品无码一区二区三区| 亚洲av永久无码精品古装片| 亚洲欧美精品AAAAAA片| 亚洲精品tv久久久久久久久| 亚洲一级Av无码毛片久久精品| 日韩精品亚洲专区在线观看| 四虎精品成人免费视频| 亚洲国产精品碰碰| 亚洲欧美日韩国产精品专区 | 午夜亚洲av永久无码精品| 欧美国产成人精品一区二区三区 | 精品九九久久国内精品| 久久精品国产亚洲一区二区| 日韩麻豆国产精品欧美| 999久久久免费国产精品播放| 91精品国产品国语在线不卡| 99精品国产一区二区| 国产精品成人无码久久久久久| 国产精品内射久久久久欢欢|