Hive分析窗口函数—窗口和over()开窗函数

By timebusker on February 11, 2018

窗口就是分析函数分析时要处理的数据范围,就拿sum来说,它是sum窗口中的记录而不是整个分组中的记录, 因此我们在想得到某个栏位的累计值时,我们需要把窗口指定到该分组中的第一行数据到当前行, 如果你指定该窗口从该分组中的第一行到最后一行,那么该组中的每一个sum值都会一样,即整个组的总和。

窗口子句中我们经常用到指定第一行当前行最后一行这样的三个属性。

  • 第一行unbounded preceding
  • 当前行是 current row`
  • 最后一行unbounded following
  • 往前N行n preceding
  • 往后N行n following

窗口子句不能单独出现,必须有order by子句时才能出现。

last_value(sal) over(partition by deptno by sal rows between unbounded preceding and current row)

以上示例指定窗口为整个分组。而出现order by子句的时候,不一定要有窗口子句,但效果会很不一样, 此时的窗口默认是当前组的第一行到当前行(不指定窗口字句时的默认值)

  • 当省略窗口子句时
    • 如果存在order by则默认的窗口是unbounded preceding and current row–当前组的第一行到当前行
    • 如果同时省略order by则默认的窗口是unbounded preceding and unbounded following–整个组
  • 如果省略分组,则把全部记录当成一个组
    • 如果存在order by则默认窗口是unbounded preceding and current row–当前组的第一行到当前行
    • 如果这时省略order by则窗口默认为unbounded preceding and unbounded following–整个组

sql无排序,over()排序子句省略 ==> 窗口代表整个分组

SELECT DEPTNO, EMPNO, ENAME, SAL, 
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO)
FROM EMP;

sql无排序,over()排序子句有,窗口省略 ==> 窗口使用默认值:unbounded preceding and current row

SELECT DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO 
                            ORDER BY SAL DESC)
  FROM EMP;

sql无排序,over()排序子句有,窗口也有,窗口特意强调全组数据 ==> 窗口代表指定区域内运行分析函数分析

SELECT DEPTNO,
       EMPNO,
       ENAME,
       SAL,
       LAST_VALUE(SAL) 
       OVER(PARTITION BY DEPTNO 
            ORDER BY SAL 
            ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) MAX_SAL
  FROM EMP;

sql有排序,over()排序子句无 ==> 先做sql排序再使用默认窗口进行分析函数运算

SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       LAST_VALUE(SAL) OVER(PARTITION BY DEPTNO) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR;

sql有排序(倒序),over()排序子句有,窗口子句无 ==> sql先选数据但是不排序,而后排序子句先排序并进行分析函数处理(窗口默认为第一行到当前行),最后再进行sql排序,使用默认窗口

SELECT DEPTNO,
       MGR,
       ENAME,
       SAL,
       HIREDATE,
       MIN(SAL) OVER(PARTITION BY DEPTNO ORDER BY SAL ASC) LAST_VALUE
  FROM EMP
 WHERE DEPTNO = 30
 ORDER BY DEPTNO, MGR DESC;