分析函数用法及窗口子句 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;

 

 

 

 

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