SQL:分析函数、排名函数、聚合函数配合窗口函数 OVER 的用法
參考 1:Microsoft 中的 SQL Server 文檔(分析函數、排名行數、聚合函數、OVER窗口函數)
參考 2:SQL Server 分析函數和排名函數 博主:悅光陰
分析函數基于分組,計算分組內數據的聚合值,經常會和窗口函數OVER()一起使用,使用分析函數可以很方便地計算同比和環比,獲得中位數,獲得分組的最大值和最小值。
分析函數和聚合函數不同,不需要GROUP BY子句,對SELECT子句的結果集,通過OVER()子句分組;
一,分析函數
分析函數通常和 OVER() 函數搭配使用,SQL Server 中共有4類分析函數。
注意:distinct 子句的執行順序是在分析函數之后。
1,分布函數:CUME_DIST、PERCENT_RANK
功能:計算某個值在某個值組內的累積分布;換言之,CUME_DIST計算某指定值在一組值中的相對位置。
CUME_DIST 計算的邏輯是:小于等于當前值的行數 / 分組內總行數;
PERCENT_RANK 計算的邏輯是:(分組內當前行的 RANK 值-1)/ (分組內總行數-1),排名值是 RANK() 函數排序的結果值;
示例:
select Department
,LastName
,Rate
,cume_dist() over(partition by Department order by Rate) as CumeDist
,percent_rank() over(partition by Department order by Rate) as PtcRank
,rank() over(partition by Department order by Rate asc) as rank_number
,count(0) over(partition by Department) as count_in_group
from #data
order by DepartMent
,Rate desc
2,分布函數:PERCENTILE_CONT、PERCENTILE_DISC
功能:
都是為了計算百分位的數值,比如計算在某個百分位時某個欄位的數值是多少;
如,20% —— 一組數據中,分布位置在 20% 處的數值、50% —— 分布位置在 50% 處的數值,也就是中位數;
語法:
PERCENTILE_CONT ( numeric_literal ) WITHIN GROUP ( ORDER BY order_by_expression [ ASC | DESC ] ) OVER ( [ <partition_by_clause> ] ) PERCENTILE_DISC ( numeric_literal ) WITHIN GROUP ( ORDER BY order_by_expression [ ASC | DESC ] ) OVER ( [ <partition_by_clause> ] )
區別:
這兩個函數的區別是前者是連續型,后者是離散型。
CONT代表continuous,連續值,DISC代表discrete,離散值。
PERCENTILE_CONT是連續型,意味它考慮的是區間,所以值是絕對的中間值;
PERCENTILE_DISC是離散型,所以它更多考慮向上或者向下取舍,而不會考慮區間;
示例:
select Department
,LastName
,Rate
,PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY Rate) OVER (PARTITION BY Department) AS MedianCont
,PERCENTILE_DISC(0.5) WITHIN GROUP (ORDER BY Rate) OVER (PARTITION BY Department) AS MedianDisc
,row_number() over(partition by Department order by Rate) as rn
from #data
order by DepartMent
,Rate asc
3,偏移函數:LAG、LEAD
功能:
對某列數據進行偏移;
區別:
LAG:向下偏移 —— 如果偏移 n 行數據(即 offset=n),舊列中的第一行數據,在新列中為第 n+1 行數據;
LEAD:向上偏移 —— 如果偏移 n 行數據(即 offset=n),舊列中的第一行數據,在新列中為第 n+1 行數據,
語法:
LAG (scalar_expression [,offset] [,default])
OVER ( [ partition_by_clause ] order_by_clause )
LEAD ( scalar_expression [ ,offset ] , [ default ] )
OVER ( [ partition_by_clause ] order_by_clause )
sclar_expression
偏移的對象,即 舊列;
offset
偏移量;
如,offset=n,表示偏移了 n 行數據;
默認值是1,必須是正整數;
default
偏移后的偏移區的取值;
如, LAG 偏移了 n 行,則新列中的前 n 行的數據即為 default;
如果未指定默認值,則返回NULL;
default 可以是列,子查詢或其他表達式,但數據類型必須跟 sclar_expression 類型兼容;
示例:
結果日期,這兩個函數特別適合用于計算同比和環比;
select DepartMent
,LastName
,Rate
,lag(Rate,1,0) over(partition by Department order by LastName) as LastRate
,lead(Rate,1,0) over(partition by Department order by LastName) as NextRate
from #data
order by Department
,LastName
理解:
scalar_expression = Rate:對 Rate 列的數據進行偏移;
offset=1:偏移量設置為 1;(即偏移一行數據)
default=0:偏移區的數據設置為 0;
如新列 LastRate 的第一個分組的第 1 行數據;(向下偏移 1 行數據)
如新列 NextRate 的第一個分組的第 5 行數據;(向上偏移 1 行數據)
4,偏移函數:FIRST_VALUE、LAST_VALUE、NTH_VALUE
功能:
FIRST_VALUE:返回 scalar_expression 列中,分組中的第一行的數據;
LAST_VALUE:返回 scalar_expression 列中,分組中的最后一行的數據;
NTH_VALUE:返回 scalar_expression 列中,每個分組的偏移量;(即 offset 值)
語法:
LAST_VALUE ( [scalar_expression ) OVER ( [ partition_by_clause ] order_by_clause rows_range_clause ) FIRST_VALUE ( [scalar_expression ] ) OVER ( [ partition_by_clause ] order_by_clause [ rows_range_clause ] )
scalar_expression —— 目標列:如果對該列進行了分組和排序,則返回該列中的每個分組中的第一行 / 最后一行的數據;
示例:
USE AdventureWorks2012;
GO
SELECT Name, ListPrice,
FIRST_VALUE(Name) OVER (ORDER BY ListPrice ASC) AS LeastExpensive
FROM Production.Product
WHERE ProductSubcategoryID = 37;
理解:返回結果集中 Name 列中的第一行數據;
二,排名函數
TSQL共有4個排名函數:RANK、NTILE、DENSE_RANK、ROW_NUMBER,和 OVER() 函數搭配使用,按照特定的順序排名。
1,ROW_NUMBER
這個函數賦予唯一的連續位次;
如,有 3 條排在第1位時,排序為:1,2,3,4······
ROW_NUMBER ( ) OVER ( [ PARTITION_BY_clause ] order_by_clause )
分組內序列的最大值就是該分組內的行的數目;
2,RANK
功能:在計算排序時,若存在相同位次,會跳過之后的位次;
如,有3條排在第1位時,排序為:1,1,1,4······
RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )
3,DENSE_RANK
功能: 在計算排序時,若存在相同位次,不會跳過之后的位次。
如,有3條排在第1位時,排序為:1,1,1,2······
DENSE_RANK ( ) OVER ( [ <partition_by_clause> ] < order_by_clause > )
4,NTILE
功能:對每個分組的所有數據進行分塊標記,每個標記就是該行數據所在第幾個數據塊;
如,integer_expression=3:把一個分組的數據分成 3 分;(則每個數據塊的行數 = 分組數據總行數 / 3,如果不能整除,最后一個數據塊的數據記錄最少)
語法:
NTILE (integer_expression) OVER ( [ <partition_by_clause> ] < order_by_clause > )
示例
select Department,
LastName,
Rate,
row_number() over(order by Rate) as [row number],
rank() over(order by rate) as rate_rank,
dense_rank() over(order by rate) as rate_dense_rank,
ntile(4) over(order by rate) as quartile_by_rate
from test_data
三、聚合函數 配合 OVER 函數
一般配合 OVER 函數使用的聚合函數:SUM、COUNT、AVG、MAX、MIN;
功能:
SUM、AVG:返回累積計算結果;
如,第 n 行的數據,是從前 n 行數據中計算得到;
COUNT、MAX、MIN:返回分組中的行數、最大值、最小值,一個分組返回一行數;
語法:
對一列的分組進行計算
<窗口函數> OVER([pattition by col_a] ORDER BY col_b)
不分組,直接對某列進行計算
<窗口函數(col_a)> OVER(ORDER BY col_b)
示例:
SUM:累積求和
第 n 行數據為前 n 行數據的總和;
select product_id, product_name, sale_price,
sum(sale_price) over (order by product_id) as current_sum
from Product;
AVG:累積求平均
第 n 行的數據為前 n 行數據的平均數;
select product_id, product_name, sale_price,
avg(sale_price) over (order by product_id) as current_sum
from Product;
AVG:移動平均(一)
計算前 n 行 + 改行數據的平均值;
如,n=2:計算相鄰 3 行數據,即 (前 2 行 + 本身行數據) / 3;
如,當 n=2 時,第 10 行的數據 = (第8行 + 第9行 + 第10行) / 3
語法:
<聚合函數> OVER([PARTITION BY col_a] ORDER BY col_b ROWS n PRECEDING)
示例:
SELECT product_id, product_name, sale_price,
AVG (sale_price) OVER (ORDER BY product_id ROWS 2 PRECEDING) AS moving_avg
FROM Product;
n = 2:計算前兩行+本行數據的平均值;
第 3 行:1833 = (1000+500+4000) / 3
第 4 行:2500 = (500+4000+3000) / 3
第 5 行:4600 = (4000+3000+6800) / 3
AVG:移動平均(二)
功能:(計算上一行 + 下一行 + 該行) / 3;
語法及示例:
SELECT product_id, product_name, sale_price,
AVG(sale_price) OVER (ORDER BY product_id
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
--使用between規劃范圍,語句意思為rows 1 preceding 到 rows 1 following
FROM Product;
4600 = (4000+3000+6800) / 3
總結
以上是生活随笔為你收集整理的SQL:分析函数、排名函数、聚合函数配合窗口函数 OVER 的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab之fliplr()函数
- 下一篇: baiduaip