对hive开窗函数 over中的partition by与group by理解

name	orderdate	cost
jack	2017-01-01	10
jack	2017-02-03	23
jack	2017-01-05	46
jack	2017-04-06	42
jack	2017-01-08	55
mart	2017-04-08	62
mart	2017-04-09	68
mart	2017-04-11	75
mart	2017-04-13	94

使用如上数据。

先来直接感受一下 over中的partition by与group by。都以name字段分区

=======================gruop by=======================
select
    name,
    count(*)
from
    overdemo
where
    date_format(orderdate,'yyyy-MM')='2017-04'
group by
    name;
--------结果---------
name	_c1
jack	1
mart	4
=======================partition by========================
select
    name,
    count(*) over(partition by name)
from
    overdemo
where
    date_format(orderdate,'yyyy-MM')='2017-04';
--------结果---------
name	count_window_0
jack	1
mart	4
mart	4
mart	4
mart	4

可以看到其实两种方法的得到的结果的差别主要是partition by将所有符合过滤条件的mart都列了出来,所以,单单对于group by和over(partition by)来说,前者可以简单地看作后者的去重版。

再进一层来说,over(partition by)是group by 的升级版。因为over函数式在group by之后执行的,也就是说可以在group by 的基础上,再进行一次partition by:先group by分组且去重,然后partition by结合聚合函数(count、sum等)进行分区运算

=====同时有group by name和over(partition by name)=====
select
    name,
    count(*) over(partition by name)
from
    overdemo
where
    date_format(orderdate,'yyyy-MM')='2017-04'
group by 
    name;
---------结果--------
name	count_window_0
jack	1
mart	1
=====同时有group by name和over()=====over()无参数时结合聚合函数对全量数据进行运算
select
    name,
    count(*) over()
from
    overdemo
where
    date_format(orderdate,'yyyy-MM')='2017-04'
group by
    name;
----------结果-------
name	count_window_0
mart	2
jack	2

符合过滤条件的数据,经过group by之后得到的是去重的数据mart和jack:

①当over()无参数时,结合聚合函数count(*),对得到的数据进行计数,得到的结果就是2,并且会在mart和Jack后显示2(因为没有进行partition by name,mart和Jack是在同一个分区的)

②当over(partition by name)之后,group by得到的数据会再次进行分区,分为mart和jack,两个分区中进行count(*)计算,都只有1个,所以在两个分区中分别显示为1

此时,再解释上面只使用over(partition by name)时,为什么mart会显示4次,而且count(*)也是4。因为符合过滤条件的mart有4条,都被partition by分到了一个分区,所以count(*)的结果就是4,而且over(partition by name)并不会去重,所以显示了4次。

综上,over(partition by)可以视为group by的升级版:①会保留所有进入分区的数据,不去重(没有数据损失);②在group by之后执行,可以进行更为复杂个性化的操作

你可能感兴趣的:(Hive,#over())