分析函數用法及窗口子句 range/rows差別,及利用分析函數窗口求今日值、昨日值、上週同日值、近7天均值、30天均值 案例

分析函數的語法結構一般是:分析函數名(參數) OVER (PARTITION BY子句 ORDER BY子句 ROWS/RANGE子句)。
即由以下三部分組成:
分析函數名:如sum、max、min、count、avg等聚集函數以及lead、lag行比較函數等;
over: 關鍵字,表示前面的函數是分析函數,不是普通的集合函數;
分析子句:over關鍵字後面掛號內的內容;

分析子句又由下面三部分組成:
partition by :分組子句,表示分析函數的計算範圍,不同的組互不相干;
ORDER BY: 排序子句,表示分組後,組內的排序方式;
ROWS/RANGE:窗口子句,是在分組(PARTITION BY)後,組內的子分組(也稱窗口),此時分析函數的計算範圍窗口,而不是PARTITON。窗口有兩種,ROWS和RANGE;

注:行比較分析函數lead和lag無window(窗口)子句。


下面分析rows與range窗口子句的用法,先看下面例子:

WITH t AS
  (
  SELECT (CASE
           WHEN LEVEL IN (1, 2) THEN
            1
           WHEN LEVEL IN (4, 5) THEN
            6
           ELSE
            LEVEL
         END) ID
    FROM dual
  CONNECT BY LEVEL < 10
   )
SELECT id,
       SUM(ID) over(ORDER BY ID) default_sum,
       SUM(ID) over(ORDER BY ID RANGE BETWEEN unbounded preceding AND CURRENT ROW) range_unbound_sum,
       SUM(ID) over(ORDER BY ID ROWS BETWEEN unbounded preceding AND CURRENT ROW) rows_unbound_sum,
       SUM(ID) over(ORDER BY ID RANGE BETWEEN 1 preceding AND 2 following) range_sum,
       SUM(ID) over(ORDER BY ID ROWS BETWEEN 1 preceding AND 2 following) rows_sum
FROM t

 

從上面的例子可知:
1、窗口子句必須和order by 子句同時使用,且如果指定了order by 子句未指定窗口子句,則默認爲RANGE BETWEEN unbounded preceding AND CURRENT ROW,如上例結果集中的defult_sum等於range_unbound_sum;
2、如果分析函數沒有指定ORDER BY子句,也就不存在ROWS/RANGE窗口的計算;
3、range是邏輯窗口,是指定當前行對應值的範圍取值,列數不固定,只要行值在範圍內,對應列都包含在內,如上例中range_sum(即range 1 preceing and 2 following)例的分析結果:
當id=1時,是sum爲1-1<=id<=1+2 的和,即sum=1+1+3=5(取id爲1,1,3);
當id=3時,是sum爲3-1<=id<=3+2 的和,即sum=3(取id爲3);
當id=6時,是sum爲6-1<=id<=6+2 的和,即sum=6+6+6+7+8=33(取id爲6,6,6,7,8);
以此類推下去,結果如上例中所示。
4、rows是物理窗口,即根據order by 子句排序後,取的前N行及後N行的數據計算(與當前行的值無關,只與排序後的行號相關),如上例中rows_sum例結果,是取前1行和後2行數據的求和,分析上例rows_sum的結果:
當id=1(第一個1時)時,前一行沒數,後二行分別是1和3,sum=1+1+3=5;
當id=3時,前一行id=1,後二行id都爲6,則sum=1+3+6+6=16;
以此類推下去,結果如上例所示。
注:行比較分析函數lead和lag無window(窗口)子句。

 

----利用分析函數窗口 求近7天均值、30天均值

求 指標 今日值、昨日值、上週同日值、7日平均值、30日平均值

SELECT t.DAT,
       t.MetricName AS 指標名稱,
       t.MetricNum AS 今日值,
       lag(MetricNum) over(partition by MetricName order by DAT) 昨日值,
       lag(MetricNum, 7, NULL) over(partition by MetricName order by DAT) 上週同日值,
       AVG(MetricNum) over(partition by MetricName order by DAT ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) "7日均值",
       AVG(MetricNum) over(partition by MetricName order by DAT ROWS BETWEEN 30 PRECEDING AND CURRENT ROW) "30日均值"
  from login_time_long t;

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章