與聚合函數一樣,開窗函數也是對行集組進行聚合計算,但是普通聚合函數每組只能返回一個值,而開窗函數可以每組返回多個值。 實驗一比如我們想查詢每個工資小於5000元的員工信息(城市以及年齡),並且在每行中都顯示所有工資小於5000元的員工個數,執行下麵的SQL語句 這個語句顯然是錯誤的,因為count( ...
與聚合函數一樣,開窗函數也是對行集組進行聚合計算,但是普通聚合函數每組只能返回一個值,而開窗函數可以每組返回多個值。
實驗一
比如我們想查詢每個工資小於5000元的員工信息(城市以及年齡),並且在每行中都顯示所有工資小於5000元的員工個數,執行下麵的SQL語句
select t.fcity,t.fage,count(*) from person t where t.fsalary<5000
這個語句顯然是錯誤的,因為count()是聚合函數,然後fname和fage欄位沒有包含分組裡面。
實驗二
那麼,這樣寫呢?
select t.fcity,t.fage,count(*) from person t where t.fsalary<5000 group by t.fcity,t.fage
查詢結果
這與我們每行中都顯示所有工資小於5000元的員工個數這個條件是不符合的,那麼應該怎麼寫呢?
實驗三
select t.fcity, t.fage, (select count(*) from person f where f.fsalary < 5000) from person t where t.fsalary < 5000
查詢結果:
這次的查詢結果和我們想要的結果一樣了,但是這樣寫多了一個子查詢,非常麻煩。使用開窗函數可以大大簡化實現,下麵看一下開窗函數要實現這個效果怎麼寫
實驗四
select t.fcity, t.fage, count(*) over() from person t where t.fsalary < 5000
看下執行效果:
可以看到這個SQL語句與我們第一個實驗不同的是我們在count(*)後面加了一個over關鍵字。
開窗函數的調用格式為:
函數名(列)over(選項)
over關鍵字表示把函數當成開窗函數而不是聚合函數,SQL標準允許將所有聚合函數用做開窗函數,使用over關鍵字來區分這兩種用法。
在上面的例子中,開窗函數count(*) over()對於查詢結果的每一行都返回所有符合條件的行的條數,over關鍵字後的括弧中還經常添加選項用以改變進行聚合運算的視窗範圍(後面博客會持續更新),如果over關鍵字後的括弧中選項為空,則開窗函數會對結果集中的所有行進行聚合運算。當然,不只是count(*) over,max(fage) over(),min(fage) over()都可以。