Hive窗口函数用法

Hive 的窗口函数(或称分析函数)使你能在不改变原始结果集行数的前提下,对数据进行排序、分组、累计、排名等复杂的计算。这些函数通常与 OVER 子句一起使用,可以定义“窗口”——也就是一个数据子集,用于进行聚合、排序、偏移或其它分析计算。下面详细介绍常见的 Hive 窗口函数及其使用方法。


1. 窗口函数的基本语法

所有窗口函数都需要使用 OVER 子句,基本语法如下:

<窗口函数> OVER (
  [PARTITION BY partition_column1, partition_column2, ...]  
  [ORDER BY order_column [ASC|DESC] [,...]]
  [ROWS BETWEEN <起始行> AND <结束行>]
)
  • PARTITION BY 用于把数据分成不同的分区(组),每个分区内的窗口函数独立计算。
  • ORDER BY 用于指定分区内行的排序顺序。
  • ROWS BETWEEN 可选,用于明确定义计算范围,默认值通常为“RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”(即从分区第一行到当前行)。

2. 常见窗口函数分类及详解

2.1 排名函数

这些函数主要用于在分区内为行排序并分配排名。

  • row_number()
    为每行分配一个唯一的连续序号,排序依据 ORDER BY。
    示例:

    SELECT emp_id, salary,
           row_number() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn
    FROM employee;
    

    说明:如果同一部门中有相同薪水,row_number() 仍会为每行赋予不同的序号。

  • rank()
    根据排序为每行分配排名,相同值获得相同排名,后续排名会跳过(出现排名“空缺”)。
    示例:

    SELECT emp_id, salary,
           rank() OVER (PARTITION BY dept ORDER BY salary DESC) AS rnk
    FROM employee;
    

    说明:如果部门内最高薪水有两个人,都为 1 名,下一个人排名将是 3。

  • dense_rank()
    与 rank() 类似,但不会出现排名跳跃。
    示例:

    SELECT emp_id, salary,
           dense_rank() OVER (PARTITION BY dept ORDER BY salary DESC) AS drnk
    FROM employee;
    

    说明:如果最高薪有两个人,都为 1 名,下一个人则为 2。

  • percent_rank()
    计算当前行的排名在分区内所占比例(0~1)。
    示例:

    SELECT emp_id, salary,
           percent_rank() OVER (PARTITION BY dept ORDER BY salary DESC) AS pr
    FROM employee;
    
  • cume_dist()
    计算当前行及之前所有行占总行数的比例,即累计分布。
    示例:

    SELECT emp_id, salary,
           cume_dist() OVER (PARTITION BY dept ORDER BY salary DESC) AS cd
    FROM employee;
    
  • ntile(n)
    将分区内的行平均分为 n 组,并返回每行所在的组号(1 到 n)。
    示例:

    SELECT emp_id, salary,
           ntile(4) OVER (PARTITION BY dept ORDER BY salary DESC) AS quartile
    FROM employee;
    

2.2 偏移函数

这些函数允许你在当前行之外引用其他行的数据。

  • lag(column, offset, default)
    返回当前行前 offset 行中指定列的值。如果不存在,则返回 default(可选)。
    示例:

    SELECT emp_id, salary,
           lag(salary, 1, 0) OVER (ORDER BY emp_id) AS prev_salary
    FROM employee;
    

    说明:用于计算行与前一行之间的差异。

  • lead(column, offset, default)
    与 lag() 类似,但返回当前行之后的值。
    示例:

    SELECT emp_id, salary,
           lead(salary, 1, 0) OVER (ORDER BY emp_id) AS next_salary
    FROM employee;
    

2.3 值提取函数

这些函数用于提取窗口内的特定行的值。

  • first_value(column)
    返回窗口(通常由 ORDER BY 定义)内的第一行值。
    示例:

    SELECT emp_id, salary,
           first_value(salary) OVER (PARTITION BY dept ORDER BY hire_date) AS first_salary
    FROM employee;
    
  • last_value(column)
    返回窗口内的最后一行值。
    注意: 默认窗口框架可能只计算到当前行,故常需要使用完整窗口范围,如:

    SELECT emp_id, salary,
           last_value(salary) OVER (PARTITION BY dept ORDER BY hire_date
                                    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_salary
    FROM employee;
    

2.4 聚合窗口函数

你可以将普通聚合函数(如 sum、avg、min、max、count)与 OVER 子句结合使用,来计算累计值、移动平均等。

  • 运行累计和
    示例:
    SELECT emp_id, salary,
           sum(salary) OVER (PARTITION BY dept ORDER BY emp_id
                             ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS running_total
    FROM employee;
    
    说明:在每个部门内,按照 emp_id 排序,对薪水进行累计求和。

3. 窗口函数的使用注意事项

  • 默认窗口框架
    当仅指定 ORDER BY 时,默认窗口范围是 “RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW”。这对于累计求和、排名等常见场景很合适,但对于 last_value() 等函数,如果希望获取整个分区的最后值,可能需要明确指定窗口范围为 “ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING”。

  • 分区与排序
    使用 PARTITION BY 将数据分组,使得每个分组内的计算相互独立;使用 ORDER BY 则决定了窗口内数据的顺序,这对排名、lag/lead 函数尤为关键。

  • Hive 版本
    不同 Hive 版本对窗口函数的支持可能略有差异,部分函数(如 nth_value)在较老版本中可能不可用。建议在使用前查阅当前版本的文档。


4. 参考示例与学习资源

以下资源提供了大量关于 Hive 窗口函数的示例和详细解析:

  • 知乎专栏:《Hive sql - 常用窗口函数(万字超详解)》
  • 博客园《hive窗口分析函数使用详解系列一》

这些文章不仅介绍了窗口函数的分类,还提供了丰富的示例代码和实际业务场景案例,帮助你更好地理解和应用 Hive 窗口函数。


总结

Hive 的窗口函数为数据分析提供了灵活强大的工具,主要包括:

  • 排名函数(row_number、rank、dense_rank、percent_rank、cume_dist、ntile)
  • 偏移函数(lag、lead)
  • 值提取函数(first_value、last_value)
  • 聚合窗口函数(sum、avg、min、max、count 等)

通过结合 PARTITION BY、ORDER BY 以及适当的窗口范围定义,你可以轻松实现分组累计、移动统计、行间比较和分组排序等高级分析任务。这些函数使得在不改变原始行数的前提下,为每一行附加额外的分析信息成为可能,大大提高了数据处理和报告生成的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追梦No1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值