1. 程式人生 > >sql中的 開窗函式over() 聚合函式 排名函式

sql中的 開窗函式over() 聚合函式 排名函式

轉自:http://www.cnblogs.com/nihaoyueyue/p/5894588.html

開窗函式與聚合函式一樣,都是對行的集合組進行聚合計算。它用於為行定義一個視窗(這裡的視窗是指運算將要操作的行的集合),它對一組值進行操作,不需要使用GROUP BY子句對資料進行分組,能夠在同一行中同時返回基礎行的列和聚合列。反正我理解這個函式已經使用好子查詢或者是其它方式求得聚合列的值給我合併。

以書中的例子一步一步來介紹,假設要計算所有人員的總數,我們可以執行下面的SQL語句:

SELECT COUNT(FName) FROM T_Person

這種方式比較直接,只返回一個聚合列的值,沒有任何基礎行的列的值。但是有時需要從不在聚合函式中的行的列中訪問這些聚合計算的值(即基礎行的列)。比如我們想查詢每個工資小於5000元的員工資訊(城市以及年齡),並且在每行中都顯示所有工資小於5000 元的員工個數,嘗試編寫下面的SQL語句:

SELECT FName, FCITY, FAGE, FSalary, COUNT(FName)
FROM T_Person
WHERE FSALARY<5000

執行上面的SQL以後我們會得到下面的錯誤資訊
選擇列表中的列'T_Person.FCity' 無效,因為該列沒有包含在聚合函式或GROUP BY 子句中。
這是因為所有不包含在聚合函式中的列必須宣告在GROUP BY 子句中,使用子查詢的方式是可以解決:

複製程式碼 複製程式碼 複製程式碼
SELECT FName, FCITY, FAGE, FSalary,
(
SELECT COUNT(FName) FROM T_Person
WHERE FSALARY<5000
)
FROM T_Person
WHERE FSALARY<5000
複製程式碼 複製程式碼 複製程式碼

雖然使用子查詢能夠解決這個問題,但是子查詢的使用非常麻煩,使用開窗函式則可以大大簡化實現,下面的SQL語句展示瞭如果使用開窗函式來實現同樣的效果:

SELECT FName, FCITY, FAGE, FSalary, COUNT(FName) OVER()
FROM T_Person
WHERE FSALARY<5000

可以看到與聚合函式不同的是,開窗函式在聚合函式後增加了一個OVER關鍵字。
開窗函式的呼叫格式為:函式名(列) OVER(選項)

我這裡使用的是SQL Server 2008 R2,不知道從什麼時候開始,SQL SERVER也支援開窗函式中使用ORDER BY子句(注:書本中說MSSQLServer中是不支援開窗函式中使用ORDER BY子句)。不管怎麼樣,這裡我整合了網上的相關內容。也正因為開窗函式支援了ORDER BY子句之後,開窗函式被分為兩大類。

第一大類:聚合開窗函式====》聚合函式(列) OVER (選項),這裡的選項可以是PARTITION BY子句,但不可是ORDER BY子句

第二大類:排序開窗函式====》排序函式(列) OVER(選項),這裡的選項可以是ORDER BY子句,也可以是 OVER(PARTITION BY子句 ORDER BY子句),但不可以是PARTITION BY子句

聚合開窗函式


OVER 關鍵字表示把聚合函式當成聚合開窗函式而不是聚合函式。SQL 標準允許將所有聚合函式用做聚合開窗函式。
在上邊的例子中,開窗函式COUNT(*) OVER()對於查詢結果的每一行都返回所有符合條件的行的條數。OVER關鍵字後的括號中還經常新增選項用以改變進行聚合運算的視窗範圍。如果OVER關鍵字後的括號中的選項為空,則開窗函式會對結果集中的所有行進行聚合運算。

PARTITION BY 子句


開窗函式的OVER關鍵字後括號中的可以使用PARTITION BY 子句來定義行的分割槽來供進行聚合計算。與GROUP BY 子句不同,PARTITION BY 子句建立的分割槽是獨立於結果集的,建立的分割槽只是供進行聚合計算的,而且不同的開窗函式所建立的分割槽也不互相影響。下面的SQL語句用於顯示每一個人員的資訊以及所屬城市的人員數:

SELECT FName, FCITY, FAGE, FSalary,
COUNT(FName) OVER(PARTITION BY FCITY)
FROM T_Person

OVER(PARTITION BY FCITY)表示對結果集按照FCITY進行分割槽,並且計算當前行所屬的組的聚合計算結果。在同一個SELECT語句中可以同時使用多個開窗函式,而且這些開窗函式並不會相互干擾。比如下面的SQL語句用於顯示每一個人員的資訊、所屬城市的人員數以及同齡人的人數:

SELECT FName,FCITY, FAGE, FSalary,
COUNT(FName) OVER(PARTITION BY FCITY),
COUNT(FName) OVER(PARTITION BY FAGE)
FROM T_Person
排序開窗函式

對於排序開窗函式來講,它支援的開窗函式分別為:ROW_NUMBER(行號)、RANK(排名)、DENSE_RANK(密集排名)和NTILE(分組排名)。

先看一段SQL語句:

複製程式碼 複製程式碼 複製程式碼
select  FName, FSalary, FCity, FAge,  
row_number() over(order by FSalary) as rownum,  
rank() over(order by FSalary) as rank,  
dense_rank() over(order by FSalary) as dense_rank,  
ntile(6) over(order by FSalary)as ntile 
from  T_Person 
order by  FName  
複製程式碼 複製程式碼 複製程式碼

 執行的結果如下(對於想自己嘗試的朋友,那你得辛苦點,下載電子書或者是購買書來學習吧。因為我可是限於篇幅,省略去大部分內容哦):

 

看到上面的結果了吧,下面來介紹下相關的內容。我們得到的最終結果是按照FName進行升序顯示的。

對於row_number() over(order by FSalary) as rownum來說,這個排序開窗函式是按FSalary升序的方式來排序,並得出排序結果的序號

對於rank() over(order by FSalary) as rank來說,這個排序形容函式是按FSalary升序的方式來排序,並得出排序結果的排名號。這個函式求出來的排名結果可以排列,並列排名之後的排名將是並列的排名加上並列數(簡單說每個人只有一種排名,然後出現兩個並列第一名的情況,這時候排在兩個第一名後面的人將是第三名,也就是沒有了第二名,但是有兩個第一名)

對於dense_rank() over(order by FSalary) as dense_rank來說,這個排序函式是按FSalary升序的方式來排序,並得出排序結果的排名號。這個函式與rand()函式不同在於,並列排名之後的排名只是並列排名加1(簡單說每個人只有一種排名,然後出現兩個並列第一名的情況,這時候排在兩個第一名後面的人將是第二名,也就是兩個第一名,一個第二名)

對於ntile(6) over(order by FSalary)as ntile 來說,這個排序函式是按FSalary升序的方式來排序,然後6等分成6個組嗎,並顯示所在組的序號。

排序函式和聚合開窗函式類似,也支援在OVER子句中使用PARTITION BY語句。例如:

複製程式碼 複製程式碼 複製程式碼
select  FName, FSalary, FCity, FAge,  
row_number() over(partition by FName  order by FSalary) as rownum,  
rank() over(partition by FName order by FSalary) as rank,  
dense_rank() over(partition by FName order by FSalary) as dense_rank,  
ntile(6) over(partition by FName order by FSalary)as ntile 
from  T_Person 
order by  FName
複製程式碼 複製程式碼 複製程式碼

 關於PARTITION BY子句,請看上面的介紹,這裡就不再累贅了。但是需要注意一點的是,在排序開窗函式中使用PARTITION BY子句需要放置在ORDER BY子句之前。

相關推薦

sql開窗函式over() 聚合函式 排名函式

轉自:http://www.cnblogs.com/nihaoyueyue/p/5894588.html 開窗函式與聚合函式一樣,都是對行的集合組進行聚合計算。它用於為行定義一個視窗(這裡的視窗是指運算將要操作的行的集合),它對一組值進行操作,不需要使用GROUP BY

sql開窗函式簡單說明

開窗函式與聚合函式一樣,也是對行集組進行聚合計算,但是它不像普通聚合函式那樣每組只返回一個值,開窗函式可以為每組返回多個值,因為開窗函式所執行聚合計算的行集組是視窗。 語法:主要是over( PARTITION BY (根據某條件分組,形成一個小組)….OR

SQLAVG()、COUNT()、SUM()等函式對NULL值處理

原文連結:https://blog.csdn.net/whaxrl/article/details/51195241 一、AVG() 求平均值 注意AVE()忽略NULL值,而不是將其作為“0”參與計算 二、COUNT() 兩種用法 1、COUNT

sql兩種情況判斷(if函式)、多種情況判斷(case .. when...)

原地址:https://segmentfault.com/a/1190000009676728 sum(if(actual_num>0, share_post,0)) 其中SUM的意思淺顯易懂,求和嘛。IF也十分清晰:判斷嘛。而且if的第一個引數很明顯就是條件,

SQL Server排名函式排名開窗函式

什麼是排名函式?說實話我也不甚清楚,我知道 order by 是排序用的,那麼什麼又是排名函式呢? 接下來看幾個示例就明白了。 首先建立一個表,隨便插入一些資料。 ROW_NUMBER 函式:直接排序,ROW_NUMBER函式是以上升進行直接排序,並且以連續的順序給每一行資料一個唯一的序號。(即排名

SQL Server聚合函式聚合開窗函式

以下面這個表的資料作為示例。 什麼是聚合函式? 聚合函式:聚合函式就是對一組值進行計算後返回單個值(即分組)。聚合函式在計算時都會忽略空值(null)。 所有的聚合函式均為確定性函式。即任何時候使用一組相同的輸入值呼叫聚合函式執行後的返回值都是相同的,無二義性。 COUNT(統計函式):COUNT

SQL的視窗函式 OVER視窗函式

SQL/OR   與聚集函式一樣,視窗函式也針對定義的行集(組)執行聚集,但它不像聚集函式那樣每組之返回一個值,視窗函式可以為每組返回多個值。實際上,DB2中稱這種函式為聯機分析處理OLAP函式,而Oracle把它們稱為解析函式,但ISO SQL標準把它們稱為視窗函式。視窗函式一般

關於sql聚合函式

    聚合函式一般和 group by 一起使用,但是也能單獨使用(前提 sql只返回一個欄位的值)。   1.和group by配合使用,查詢分組後同一個欄位多條資料的聚合值。 2.單獨使用時,規定只能返回一個欄位的值。 select  S

sql聚合函式加舉例

聚合函式是對一組值執行計算並返回單一的值的函式,它經常與SELECT語句的GROUP BY子句一同使用,SQL SERVER 中具體有哪些聚合函式呢?我們來一一看一下:1. AVG 返回指定組中的平均值,空值被忽略。例:select prd_no,avg(qty) from

Sql server 開窗函式over()的語法

用法一:與ROW_NUMBER()函式結合用,給結果進行排序編號,如圖: 程式碼如下: SELECT ROW_NUMBER() over(order by RequiredDate) num ,* from [Northwind].[dbo]

SQL 開窗函式over 與sum(),AVG(),MIN(),MAX()

1.使用over子句與rows_number()以及聚合函式進行使用,可以進行編號以及各種操作。而且利用over子句的分組效率比group by子句的效率更高。 2.在訂單表(order)中統計中,生成這麼每一條記錄都包含如下資訊:“所有訂單的總和”、“每一位客戶的所有訂單的

SQL/HQL開窗函式詳細講解

一、前言 本文將從一道面試題入手,以一種易人理解的方式,將對SQL視窗函式部分進行詳細講解。 開窗函式,顧名思義,就是從現有的表上,額外多加一列出來展示,這也是從視覺上來講最直觀的體驗。 二、思維拓展 注:MYSQL中無開窗函式 開窗函式分為兩大類: 1、分組

SQL開窗函式詳解--可代替聚合函式使用

       在沒學習開窗函式之前,我們都知道,用了分組之後,查詢欄位就只能是分組欄位和聚合的欄位,這帶來了極大的不方便,有時我們查詢時需要分組,又需要查詢不分組的欄位,每次都要又到子查詢,這樣顯得sql語句複雜難懂,給維護程式碼的人帶來很大的痛苦,然而開窗函數出現了,

SQL排序函式的用法

SQL中的排序函式有三:1、row_number() over();2、rank() over();3、dense_rank() over(),具體用法如下: 1.row_number() over(partition by 列名 order by 列名 [desc]) 其中,partition by 是分組

SQL的四大排名函式

row_number() 根據列為結果集中的行返回有序數字 select employeeID,row_number()over (order by salary asc) as Rank  from employee 查詢結果會有一個Ran

Oracle和MySQL的不同函式的等價作用(在MySQL實現Rank高階排名函式)重點推薦

mysql與Oracle的區別 https://blog.csdn.net/qq686867/article/details/79355760 mysql試題 https://zhuanlan.zhihu.com/p/38047497 https://blog.csdn.net/Br

sql的正則函式

SQL 中的正則函式 ORACLE中支援正則表示式的函式主要有下面四個: 1,REGEXP_LIKE :與LIKE的功能相似,比LIKE強大得多。 2,REGEXP_INSTR :與INSTR的功能相似。 3,REGEXP_SUBSTR :與SUBSTR的功能相似。 4,REGEXP_REPLA

sql的case函式

功能 計算條件列表,並返回多個可能的結果表示式之一。可以在sql中對欄位進行簡單的處理。 語法 case語句有簡單表示式和搜尋表示式兩種用法,格式如下: --Simple CASE expression: CASE input_expression WHEN w

SQL的CAST()函式

一、語法: CAST (expression AS data_type)引數說明:expression:任何有效的SQServer表示式。AS:用於分隔兩個引數,在AS之前的是要處理的資料,在AS之後是要轉換的資料型別。data_type:目標系統所提供的資料型別,包括bi

oracle------分析函式開窗函式over( )

一  什麼是分析函式   1  概念   分析函式是Oracle專門用於解決複雜報表統計需求的功能強大的函式,它可以在資料中進行分組然後計算基於組的某種統計值,並且每一組的每一行都可以返回一個統計值