目錄
#OVER的定義
OVER的語法
OVER的用法
OVER在聚合函數中使用的範例
SUM後的開窗函數
COUNT後的開窗函數
OVER在排序函數中使用的範例
ROW_NUMBER()
DENSE_RANK() 
NTILE()
总结
首頁 資料庫 SQL 一文搞懂SQL中的開窗函數

一文搞懂SQL中的開窗函數

Sep 02, 2022 pm 04:55 PM
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
登入後複製

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

結果如下:

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

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
登入後複製

傳回的結果如下圖:

後面的每個開窗函數就不再一一解讀了,可以對照上面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;
登入後複製

結果如下:

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

此外ROW_NUMBER()函數也可以取指定順序的資料。

SELECT * FROM (
SELECT *, ROW_NUMBER() OVER (ORDER BY SCORE DESC) AS 总排序
FROM Scores
) t WHERE t.总排序=2;
登入後複製

結果如下:

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;
登入後複製

結果:

其中上圖是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;
登入後複製

结果如下:

上面是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;
登入後複製

结果如下:

就是将查询出来的记录根据NTILE函数里的参数进行平分分区。

总结

OVER开窗函数是我们工作中经常要使用到的,特别是在做数据分析计算的时候,经常要对数据进行分组排序。上面我们额外介绍了聚合函数和排序函数的与OVER结合的使用方法,此外还有很多与OVER一起使用的函数,比如LEAD函数,LAG函数,STRING_AGG函数等等都会使用到开窗函数OVER,其使用方法也要务必掌握。

推荐学习:《SQL教程

以上是一文搞懂SQL中的開窗函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Hibernate 框架中 HQL 和 SQL 的差異是什麼? Hibernate 框架中 HQL 和 SQL 的差異是什麼? Apr 17, 2024 pm 02:57 PM

HQL和SQL在Hibernate框架中進行比較:HQL(1.物件導向語法,2.資料庫無關的查詢,3.類型安全),而SQL直接操作資料庫(1.與資料庫無關的標準,2.可執行複雜查詢和資料操作)。

Oracle SQL中除法運算的用法 Oracle SQL中除法運算的用法 Mar 10, 2024 pm 03:06 PM

《OracleSQL中除法運算的用法》在OracleSQL中,除法運算是常見的數學運算之一。在資料查詢和處理過程中,除法運算可以幫助我們計算欄位之間的比例或得出特定數值的邏輯關係。本文將介紹OracleSQL中除法運算的用法,並提供具體的程式碼範例。一、OracleSQL中除法運算的兩種方式在OracleSQL中,除法運算可以用兩種不同的方式來進行

Oracle與DB2的SQL語法比較與區別 Oracle與DB2的SQL語法比較與區別 Mar 11, 2024 pm 12:09 PM

Oracle和DB2是兩個常用的關聯式資料庫管理系統,它們都有自己獨特的SQL語法和特性。本文將針對Oracle和DB2的SQL語法進行比較與區別,並提供具體的程式碼範例。資料庫連接在Oracle中,使用以下語句連接資料庫:CONNECTusername/password@database而在DB2中,連接資料庫的語句如下:CONNECTTOdataba

詳解MyBatis動態SQL標籤中的Set標籤功能 詳解MyBatis動態SQL標籤中的Set標籤功能 Feb 26, 2024 pm 07:48 PM

MyBatis動態SQL標籤解讀:Set標籤用法詳解MyBatis是一個優秀的持久層框架,它提供了豐富的動態SQL標籤,可以靈活地建構資料庫操作語句。其中,Set標籤是用來產生UPDATE語句中SET子句的標籤,在更新作業中非常常用。本文將詳細解讀MyBatis中Set標籤的用法,以及透過具體的程式碼範例來示範其功能。什麼是Set標籤Set標籤用於MyBati

SQL中的identity屬性是什麼意思? SQL中的identity屬性是什麼意思? Feb 19, 2024 am 11:24 AM

SQL中的Identity是什麼,需要具體程式碼範例在SQL中,Identity是一種用於產生自增數字的特殊資料類型,它常用於唯一識別表中的每一行資料。 Identity欄位通常與主鍵列搭配使用,可確保每筆記錄都有獨一無二的識別碼。本文將詳細介紹Identity的使用方式以及一些實際的程式碼範例。 Identity的基本使用方式在建立表格時,可以使用Identit

Springboot+Mybatis-plus不使用SQL語句進行多表新增怎麼實現 Springboot+Mybatis-plus不使用SQL語句進行多表新增怎麼實現 Jun 02, 2023 am 11:07 AM

在Springboot+Mybatis-plus不使用SQL語句進行多表添加操作我所遇到的問題準備工作在測試環境下模擬思維分解一下:創建出一個帶有參數的BrandDTO對像模擬對後台傳遞參數我所遇到的問題我們都知道,在我們使用Mybatis-plus中進行多表操作是極其困難的,如果你不使用Mybatis-plus-join這一類的工具,你只能去配置對應的Mapper.xml文件,配置又臭又長的ResultMap,然後再寫對應的sql語句,這種方法雖然看上去很麻煩,但具有很高的靈活性,可以讓我們

SQL出現5120錯誤怎麼解決 SQL出現5120錯誤怎麼解決 Mar 06, 2024 pm 04:33 PM

解決方法:1、檢查登入使用者是否具有足夠的權限來存取或操作該資料庫,確保該使用者俱有正確的權限;2、檢查SQL Server服務的帳戶是否具有存取指定檔案或資料夾的權限,確保該帳戶具有足夠的權限來讀取和寫入該文件或資料夾;3、檢查指定的資料庫文件是否已被其他進程打開或鎖定,嘗試關閉或釋放該文件,並重新運行查詢;4、嘗試以管理員身份運行Management Studio等等。

如何使用SQL語句在MySQL中進行資料聚合和統計? 如何使用SQL語句在MySQL中進行資料聚合和統計? Dec 17, 2023 am 08:41 AM

如何使用SQL語句在MySQL中進行資料聚合和統計?在進行資料分析和統計時,資料聚合和統計是非常重要的步驟。 MySQL作為一個功能強大的關聯式資料庫管理系統,提供了豐富的聚合和統計函數,可以很方便地進行資料聚合和統計操作。本文將介紹使用SQL語句在MySQL中進行資料聚合和統計的方法,並提供具體的程式碼範例。一、使用COUNT函數進行計數COUNT函數是最常用

See all articles