91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SQL中的開窗函數怎么使用

發布時間:2022-08-25 14:55:32 來源:億速云 閱讀:223 作者:iii 欄目:開發技術

這篇文章主要介紹“SQL中的開窗函數怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“SQL中的開窗函數怎么使用”文章能幫助大家解決問題。

窗口函數

  • 簡單理解,就是對查詢的結果多出一列,這一列可以是聚合值,也可以是排序值。

  • 開窗函數一般就是說的是over()函數,其窗口是由一個 OVER 子句 定義的多行記錄

  • 開窗函數一般分為兩類,聚合開窗函數和排序開窗函數。

簡單來說,窗口函數有以下功能:

1)同時具有分組和排序的功能

2)不減少原表的行數

3)語法如下:

<窗口函數> over (partition by <用于分組的列名>
                order by <用于排序的列名> [rows between ?? and ???])

<窗口函數>的位置,可以放以下兩種函數:

1) 專用窗口函數,包括后面要講到的rank, dense_rank, row_number等專用窗口函數。

2) 聚合函數,如sum(). avg(), count(), max(), min()等,rows between&hellip;and&hellip;

因為窗口函數是對where或者group by子句處理后的結果進行操作,所以窗口函數原則上只能寫在select子句中。

3)業務需求“在每組內排名”,比如:

  • 排名問題:每個部門按業績來排名

  • topN問題:找出每個部門排名前N的員工進行獎勵

1.1 排序窗口函數rank

-- 如果我們想在每個班級內按成績排名,得到下面的結果。
select *,
   rank() over (partition by 班級
                 order by 成績 desc) as ranking
from 班級表;

我們來解釋下這個sql語句里的select子句。rank是排序的函數。要求是“每個班級內按成績排名”,這句話可以分為兩部分:

1)每個班級內:按班級分組

  • partition by用來對表分組。在這個例子中,所以我們指定了按“班級”分組(partition by 班級)

2)按成績排名

  • order by子句的功能是對分組后的結果進行排序,默認是按照升序(asc)排列。在本例中(order by 成績 desc)是按成績這一列排序,加了desc關鍵詞表示降序排列。

通過下圖,我們就可以理解partiition by(分組)和order by(在組內排序)的作用了。 

SQL中的開窗函數怎么使用

group by分組匯總后改變了表的行數,一行只有一個類別。而partiition by和rank函數不會減少原表中的行數。

SQL中的開窗函數怎么使用

注意事項

  • partition子句可是省略,省略就是不指定分組,只是按成績由高到低進行了排序。但是,這就失去了窗口函數的功能,所以一般不要這么使用。

  • 窗口函數原則上只能寫在select子句中

1.2 rank(), dense_rank(), row_number()區別

select *,
   rank() over (order by 成績 desc) as ranking,
   dense_rank() over (order by 成績 desc) as dese_rank,
   row_number() over (order by 成績 desc) as row_num
from 班級表

得到結果:

SQL中的開窗函數怎么使用

從上面的結果可以看出:

  • rank函數:這個例子中是5位,5位,5位,8位,也就是如果有并列名次的行,會占用下一名次的位置。比如正常排名是1,2,3,4,但是現在前3名是并列的名次,結果是:1,1,1,4。

  • dense_rank函數:這個例子中是5位,5位,5位,6位,也就是如果有并列名次的行,不占用下一名次的位置。比如正常排名是1,2,3,4,但是現在前3名是并列的名次,結果是:1,1,1,2。

  • row_number函數:這個例子中是5位,6位,7位,8位,也就是不考慮并列名次的情況。比如前3名是并列的名次,排名是正常的1,2,3,4。

1.3 排序截取數據lag(),lead(),ntile(),cume_dist()

  • LAG(col,n,default_val):獲取往前第n行數據,col是列名,n是往上的行數,當第n行為null的時候取default_val

  • LEAD(col,n, default_val):往后第n行數據,col是列名,n是往下的行數,當第n行為null的時候取default_val

  • NTILE(n):把有序分區中的行分發到指定數據的組中,各個組有編號,編號從1開始,對于每一行,NTILE返回此行所屬的組的編號。

  • cume_dist(),計算某個窗口或分區中某個值的累積分布。假定升序排序,則使用以下公式確定累積分布:

小于等于當前值x的行數 / 窗口或partition分區內的總行數。其中,x 等于 order by 子句中指定的列的當前行中的值。

1.4 聚合函數作為窗口函數

聚和窗口函數和上面提到的專用窗口函數用法完全相同,只需要把聚合函數寫在窗口函數的位置即可,但是函數后面括號里面不能為空,需要指定聚合的列名。

我們來看一下窗口函數是聚合函數時,會出來什么結果:

select *,
   sum(成績) over (order by 學號) as current_sum,
   avg(成績) over (order by 學號) as current_avg,
   count(成績) over (order by 學號) as current_count,
   max(成績) over (order by 學號) as current_max,
   min(成績) over (order by 學號) as current_min
from 班級表

SQL中的開窗函數怎么使用

如上圖,聚合函數sum在窗口函數中,是對自身記錄、及位于自身記錄以上的數據進行求和的結果。比如0004號,在使用sum窗口函數后的結果,是對0001,0002,0003,0004號的成績求和,若是0005號,則結果是0001號~0005號成績的求和,以此類推。

不僅是sum求和,平均、計數、最大最小值,也是同理,都是針對自身記錄、以及自身記錄之上的所有數據進行計算,

這樣使用窗口函數有什么用呢?

聚合函數作為窗口函數,可以在每一行的數據里直觀的看到,截止到本行數據,統計數據是多少(最大值、最小值等)。同時可以看出每一行數據,對整體統計數據的影響。

1.5 over(- - rows between and )

sum()/... over ([partition by 列名] [order by 列名] [rows between ... and ...] )
-- 從起點到當前行數據聚合
between unbounded preceding and current row 
-- 往前2行到往后1行的數據聚合
between 2 preceding and 1 following

rows必須跟在Order by 子句之后,對排序的結果進行限制,使用固定的行數來限制分區中的數據行數量。

  • OVER():指定分析函數工作的數據窗口大小,這個數據窗口大小可能會隨著行的變而變化。

  • CURRENT ROW:當前行

  • n PRECEDING:往前n行數據

  • n FOLLOWING:往后n行數據

  • UNBOUNDED:起點,unbounded preceding 表示從表數據的起點, unbounded following表示到后面的終點

select name,subject,score,
sum(score) over() as sum1,
sum(score) over(partition by subject) as sum2,
sum(score) over(partition by subject order by score) as sum3, 
-- 由起點到當前行的窗口聚合,和sum3一樣
sum(score) over(partition by subject order by score rows between unbounded preceding and current row) as sum4, 
-- 當前行和前面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 preceding and current row) as sum5,
-- 當前行的前面一行和后面一行的窗口聚合
sum(score) over(partition by subject order by score rows between 1 preceding AND 1 following) as sum6,
-- 當前和后面所有的行
sum(score) over(partition by subject order by score rows between current row and unbounded following) as sum7
from t_fraction;
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+
| name  | subject  | score  | sum1  | sum2  | sum3  | sum4  | sum5  | sum6  | sum7  |
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+
| 孫悟空   | 數學       | 12     | 359   | 185   | 12    | 12    | 12    | 31    | 185   |
| 沙悟凈   | 數學       | 19     | 359   | 185   | 31    | 31    | 31    | 104   | 173   |
| 豬八戒   | 數學       | 73     | 359   | 185   | 104   | 104   | 92    | 173   | 154   |
| 唐玄奘   | 數學       | 81     | 359   | 185   | 185   | 185   | 154   | 154   | 81    |
| 豬八戒   | 英語       | 11     | 359   | 80    | 11    | 11    | 11    | 26    | 80    |
| 孫悟空   | 英語       | 15     | 359   | 80    | 26    | 26    | 26    | 49    | 69    |
| 唐玄奘   | 英語       | 23     | 359   | 80    | 49    | 49    | 38    | 69    | 54    |
| 沙悟凈   | 英語       | 31     | 359   | 80    | 80    | 80    | 54    | 54    | 31    |
| 孫悟空   | 語文       | 10     | 359   | 94    | 10    | 10    | 10    | 31    | 94    |
| 唐玄奘   | 語文       | 21     | 359   | 94    | 31    | 31    | 31    | 53    | 84    |
| 沙悟凈   | 語文       | 22     | 359   | 94    | 53    | 53    | 43    | 84    | 63    |
| 豬八戒   | 語文       | 41     | 359   | 94    | 94    | 94    | 63    | 63    | 41    |
+-------+----------+--------+-------+-------+-------+-------+-------+-------+-------+

關于“SQL中的開窗函數怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

sql
AI

平乐县| 友谊县| 香河县| 景德镇市| 镇安县| 东丽区| 车致| 岑巩县| 武穴市| 平阴县| 山阳县| 枣庄市| 河池市| 洮南市| 晋城| 南乐县| 乌拉特中旗| 从江县| 上高县| 大姚县| 休宁县| 勐海县| 祥云县| 鹤山市| 延安市| 荃湾区| 平陆县| 皋兰县| 台中市| 易门县| 甘洛县| 景宁| 玉门市| 潼关县| 施甸县| 远安县| 阳谷县| 孟州市| 凯里市| 延寿县| 乐至县|