hive开窗函数学习

hive 开窗函数

  • 什么是开窗函数

    我们想要对一组数据进行操作的时候,一般需要的是对数据进行聚合操作,例如通过group by,然后进行求解sum,count,avg等,这时候返回的是一个值,可以理解为多对一的关系,如果我买了想要获取需要聚合数据的多对多关系呢,那就需要开窗函数,为窗口中的每一行数据返回一个值。

    具体来说就是:

    窗口函数对一组行进行操作,并为基础查询中的每一行返回一个值。术语窗口描述函数操作的一组行。窗口函数使用窗口中行的值来计算返回值。

  • 怎么定义窗口

    在查询中使用窗口函数时,使用**over()**子句定义窗口。over()子句将窗口函数与其他分析和报告函数区分开来。查询可以包含具有相同或不同窗口定义的多个窗口函数。

  • 开窗函数可以分为三类:

    • 聚合类型
    • 排序类型
    • 值类型
  • 聚合类型

    聚合类的开窗函数有count(), avg(), max(), min(),sum()

    下面仅以count举例,其他的类型

    • count()

      返回一个bigint类型,基本用法和聚合函数里面的用法类似。

      假设有这么个需求,需要获取每个员工所在部门的人数:

      select 
          name, dep_name, count(name) over(partition by dep_name) as count
      from test;
      

      如上面的查询语句,over定义了一个根据dep_nam分区的窗口,那么count的基础就是dep_name的集合,返回的就是每个部门的人数,当然不用开窗函数的话使用join也可以实现相同的功能。

      over内支持partiion by order by, rows between * and *指定范围等

  • 排序类型

    排序类型的开窗函数有rank(), row_number(), dense_rank(), percent_rank(), ntile(), cume_dist()

    • rank()

      返回的是一个bigint类型,是一个值基于over子句中order by 在一组中的排名,如果partition by存在的话,则是为每个分区中的每个值排名。排名可能不是连续的,如果有几个相等的排名,比如两个1,,则下一个排名就是3

      select *, 
             rank() over() as rank1,
             --对所有员工年龄进行排序
             rank() over(order by age) as rank2,
             --对每个部门的员工年龄进行排序
             rank() over(partition by dep_name order by age) as rank3
      from
          test;
      

      hive开窗函数学习_第1张图片

      可以看到如果over内不指定的话默认都是1,后面两列分别是根据所有员工和部门员工的年龄进行分类。

    • dense_rank()

      和rank()的不同之处在于排名是连续的。

      select name, dep_name, dense_rank() over(order by age) from test;
      

      hive开窗函数学习_第2张图片

      可以看到即使是有多个重复排名,下一位的排名也是连续的,多个1之后还是2

    • percent_rank()

      顾名思义,计算给定行的百分比,计算公式是:(当前行的rank值-1)/(分组内的总行数-1)

      select name,
             salary,
             percent_rank() over(order by salary),
             percent_rank() over(partition by dep_name order by salary)
      from
          test
      

    hive开窗函数学习_第3张图片

    • row_number()

      从1开始对分区内的数据排序,和dense_rank不同的是同一分区相同的值具有不同的排序

      select name, dep_name, age,
             row_number() over(partition by dep_name order by age) 
      from test;
      

      hive开窗函数学习_第4张图片

      可以

    • ntile()

      将分区中已排序的行划分为大小尽可能相等的指定数量的排名的组,并返回给定行所在的组的排名。

      select name, age, ntile(3) over(order by age) from test;
      

      hive开窗函数学习_第5张图片

      将所有人按照年龄分为3组,每人对应的分组

    • cume_dist()

      计算某个窗口或分区中某个值的累积分布

      select name,
             cume_dist() over(order by age) as cume1,
             cume_dist() over(order by age asc) as cum2,
             cume_dist() over(order by age desc) as cum3
      from test
      

      hive开窗函数学习_第6张图片

      可以看到默认是按照升序处理的

      值类型开窗函数

      有first_value(), last_value(), lag(),lead()

      • first_value(), last_value()

        返回的是分区中第一个和最后一个值

        select
            first_value(age) over(partition by dep_name),
            last_value(age) over(partition by dep_name order by age)
        from
            test
        
      • lag(), lead()

        用于统计窗口内往上/下第n个值

        参数: col: 基准列;n:向上/下第n行,default:如果值为null时的默认值

        select name, lag(age, 3,10) over(partition by dep_name),
               lead(age, 10, 2) over()
        from
            test
        

    大数据,Java, Python:www.gqber.cn

你可能感兴趣的:(hive开窗函数学习)