Hive窗口函数(开窗函数)

本文深入讲解SQL窗口函数的使用,包括over(), lag(), lead(), ntile()等函数的语法和应用场景,通过具体实例演示如何在Hive中进行数据查询、聚合和分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、相关函数说明

  • over():指定聚合函数工作的数据窗口的大小,这个数据窗口大小会随着行的变而变化。over跟在聚合函数后面,只对聚合函数生效。
  • current row:当前行
  • n preceding:往前n行数据
  • n following:往后n行数据
  • unbounded:起点:unbounded preceding 表示从前面的起点开始,unbounded following表示到后面的终点结束
  • lag(col,n):往前第n行数据
  • lead(col,n):往后第n行数据
  • ntile(n):把有序分区中的行分发到指定数据的组中,各个组有编号,编号从1开始,对于每一行,ntile返回此行所属的组的编号。注意:n必须为int类型。

二、实列说明

应用表如下:
在这里插入图片描述
1、创建hive表并导入数据

create table business(
name string, 
orderdate string,
cost int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
load data local inpath "/opt/module/datas/business.txt" into table business;

2、按需求查询数据
(1)查询在2017年4月份购买过的顾客及总人数

select 
    distinct name,
    count( distinct name) over()
from
    business   
where 
    substring(orderdate,1,7)='2017-04';

或者:

select
    name,
    count(*) over()
from 
    business
where
    substring(orderdate,1,7)='2017-04'
group by name;

查询结果:
在这里插入图片描述

(2)查询顾客的购买明细及月购买总额

select 
    *,
    sum(cost) over(partition by month(orderdate))
from
    business;

查询结果:
在这里插入图片描述

tips:month函数说明:SELECT MONTH('2008-02-03'); # 2

(3)上述的场景, 将每个顾客的cost按照日期进行累加

 select 
    *,
    sum(cost) over(partition by name order by orderdate asc
    rows between unbounded preceding and current row)
from 
    business;

查询结果:
在这里插入图片描述

select name,orderdate,cost, 
sum(cost) over() as sample1,--所有行相加 
sum(cost) over(partition by name) as sample2,--按name分组,组内数据相加 
sum(cost) over(partition by name order by orderdate) as sample3,--按name分组,组内数据累加 
sum(cost) over(partition by name order by orderdate rows between UNBOUNDED PRECEDING and current row ) as sample4 ,--和sample3一样,由起点到当前行的聚合 
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING and current row) as sample5, --当前行和前面一行做聚合 
sum(cost) over(partition by name order by orderdate rows between 1 PRECEDING AND 1 FOLLOWING ) as sample6,--当前行和前边一行及后面一行 
sum(cost) over(partition by name order by orderdate rows between current row and UNBOUNDED FOLLOWING ) as sample7 --当前行及后面所有行 
from business;

查询结果:
在这里插入图片描述
**tips:**rows必须跟在Order by 子句之后,对排序的结果进行限制,使用固定的行数来限制分区中的数据行数量

(4)查看顾客上次的购买时间

select 
    *,
    lag(orderdate,1,'1970-01-01') over(partition by name order by orderdate) last_orderdate
from 
    business;

查询结果:
在这里插入图片描述
(5)查看顾客后面一次的购买时间

 select  
    *,
    lead(orderdate,1,"2050-01-01") over(partition by name order by orderdate) next_orderdate
from 
    business;  

查询结果:
在这里插入图片描述
(6)查询前20%时间的订单信息

 select 
    *,
    ntile(5) over(order by orderdate)
 from 
    business;

查询结果:
在这里插入图片描述

总结:

1.什么时候用开窗函数?
开窗函数常结合聚合函数使用,一般来讲聚合后的行数要少于聚合前的行数,但是有时我们既想显示聚集前的数据,又要显示聚集后的数据,这时我们便引入了窗口函数
2.窗口函数的语法:
UDAF() over (PARTITION By col1,col2 order by col3 窗口子句(rows between .. and ..) AS 列别名
注意:PARTITION By后可跟多个字段,order By只跟一个字段。

partition by子句:
一旦指定了partition by子句,聚合函数的作用范围就是分区之后的数据,这一点和group by 有些类似
 
order by子句:
order by子句对字段进行排序,如果order by子句后面没有跟rows between ** and ** 则表示起点到当前行
的聚合。order by后的rows子句近一步限制聚合函数的作用范围。
  
注意:
(1order by必须跟在partition by;2Rows必须跟在Order by子;
(3)(partition by .. order by)可替换为(distribute by .. sort by ..
### Hive 常用开窗函数概述 开窗函数是一类特殊的 SQL 函数,在查询结果的某个窗口内进行计算。这类函数不会将结果集缩减到单一行,而是保留所有行并在此基础上执行特定操作[^1]。 #### 开窗函数基本语法结构 开窗函数的一般形式如下: ```sql function_name (expression) OVER ( [PARTITION BY partition_expression] [ORDER BY sort_expression] [window_frame_clause] ) ``` - `PARTITION BY` 定义逻辑分区。 - `ORDER BY` 对指定列排序。 - `window_frame_clause` 设置窗口范围,默认情况下为整个表。 #### 常见开窗函数介绍及示例 ##### 1. 排名函数 这些函数用于给定数据集中按一定顺序排列记录,并分配相应的排名编号。 - **ROW_NUMBER()**: 返回每一分区内的唯一序号。 ```sql SELECT studentId, language, math, english, ROW_NUMBER() OVER(PARTITION BY departmentId ORDER BY math DESC) AS row_num FROM student_scores; ``` - **RANK()**: 类似于 `ROW_NUMBER()` ,但是会处理相同值的情况,即跳过重复项后的下一个自然数作为后续排名。 ```sql SELECT studentId, language, math, english, RANK() OVER(PARTITION BY departmentId ORDER BY math DESC) AS rank_val FROM student_scores; ``` - **DENSE_RANK()**: 和 `RANK()` 功能相似,区别在于不跳跃排名次序。 ```sql SELECT studentId, language, math, english, DENSE_RANK() OVER(PARTITION BY departmentId ORDER BY math DESC) AS dense_rank_val FROM student_scores; ``` ##### 2. 分析函数 此类函数主要用于统计分析目的,提供更复杂的聚合能力而不改变原始数据量级。 - **LEAD()/LAG()**: 获取当前行前后若干行的数据。 ```sql SELECT studentId, language, math, english, LAG(math, 1) OVER(ORDER BY studentId) prev_math_score, LEAD(math, 1) OVER(ORDER BY studentId) next_math_score FROM student_scores; ``` - **FIRST_VALUE/LAST_VALUE**: 取得窗口中的首个或最后一个值。 ```sql SELECT studentId, language, math, english, FIRST_VALUE(math) OVER(PARTITION BY classId ORDER BY math DESC) highest_math_in_class FROM student_scores; ``` ##### 3. 聚合函数 虽然传统意义上的聚合函数(如 SUM(), AVG() 等)也可以作为开窗函数使用,但这里主要指那些专门为窗口运算设计的功能更强的版本。 - **SUM() / COUNT() / MIN() / MAX()** 这些标准SQL聚合函数可以直接应用于窗口上下文中,从而实现更加灵活多样的数据分析需求。 ```sql SELECT studentId, language, math, english, SUM(math) OVER(PARTITION BY departmentId) total_math_by_dept FROM student_scores; ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值