hive 常用开窗函数整理

本文深入讲解SQL中的窗口函数,包括累加求和(sum),行号(row_number),排名(rank和dense_rank),以及前后值(lag和lead)的使用方法。通过具体示例,展示了如何在数据查询中利用这些函数进行复杂的数据分析。

1、sum()over(partition by ...)   (累加求和)

     select cookieid,create_time,pv,
                sum(pv) over(partition by cookieid order by createtime) as pv1,                   -- 默认为从起点到当前行
                sum(pv) over(partition by cookieid order by create_time rows between unbounded preceding and current row) as pv2, --从起点到当前行,结果同pv1 
                sum(pv) over(partition by cookieid order by create_time rows between 3 preceding and current row) as pv3,         --当前行+往前3行
                sum(pv) over(partition by cookieid order by create_time rows between 3 preceding and 1 following) as pv4,         --当前行+往前3行+往后1行
                sum(pv) over(partition by cookieid order by create_time rows between current row and unbounded following) as pv5  ---当前行+往后所有行  
   from table_test;

注释rows between 含义,也叫做window子句: 
    preceding:往前 
    following:往后 
    current row:当前行 
    unbounded:无边界,unbounded preceding 表示从最前面的起点开始, unbounded following:表示到最后面的终点 
   –其他avg,min,max,和sum用法一样
 

2、row_number()over(partition by ...)  按顺序排序 (排序eg:1,2,3,4,5,6)

      select cookieid,row_number()over(partition by cookieid order by create_time desc ) as rn from table_test;

 

3、rank()over(partition by ..,) (排序eg:1,2,2,4)
     dense_rank()over(partition by ..,)  (排序eg:1,2,2,3,3,4,5)

   select cookieid,createtime,pv,
             rank() over(partition by cookieid order by pv desc) as rank1,
            dense_rank() over(partition by cookieid order by pv desc) as d_rank2,
            row_number() over(partition by cookieid order by pv desc) as rn3 
  from table_test;

 

4、lag 和 lead 函数
   lag(col,n,default) 用于统计窗口内往上第n行值
   第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为null时候,取默认值,如不指定,则为null)

   select cookieid,create_time,pv,
          row_number() over(partition by cookieid order by createtime) as rn,
          lag(create_time,1,'1970-01-01') over(partition by cookieid order by createtime) as lag1, --根据cookieid往上一条记录的create_time
          lag(create_time,2) over(partition by cookieid order by createtime) as lag2               --根据cookieid往上弟二条记录的create_time
  from table_test;

  lead 函数则与 lag 相反: 
  lead(col,n,default) 用于统计窗口内往下第n行值
  第一个参数为列名,第二个参数为往下第n行(可选,默认为1),第三个参数为默认值(当往下第n行为null时候,取默认值,如不指定,则为null)

5、cume_dist
      percent_rank
      first_value 和 last_value 

 

 

                

     

 

<think>好的,我现在需要处理用户关于Hive开窗函数的学习请求。首先,用户明确表示是新手,需要教程和使用指导。我得确保内容结构清晰,逐步引导他们理解基本概念、语法结构,然后通过示例加深理解,最后提供常见应用场景和注意事项。首先,回忆Hive开窗函数的基础知识。开窗函数主要用于在数据的窗口范围内进行计算,比如排名、累计求和等。与普通聚合函数不同,开窗函数不会将多行合并为一行,而是保留原有行并添加计算结果。这一点需要明确说明,避免混淆。 接下来,需要整理语法结构。用户需要知道基本语法,比如OVER关键字的使用,以及如何定义窗口。要介绍PARTITIONBY、ORDER BY和窗口帧(ROWSBETWEEN)的用法。这部分可能需要分点说明,每个部分的作用和示例,比如PARTITION BY用于分组,ORDERBY用于排序,窗口帧定义计算范围。然后,示例部分很重要。新手通过实际例子更容易理解。比如,使用ROW_NUMBER()进行分组排序,SUM()计算累计值,RANK()处理排名。每个示例需要给出具体的SQL语句和结果说明,让用户能对照着练习。同时,要注意示例的多样性,涵盖不同的函数类型和窗口设置。常见应用场景部分可以帮助用户了解何时使用开窗函数。比如TopN分析、累计计算、移动平均等。这些场景贴近实际工作,能增强用户的学习动力。需要简要说明每个场景的问题和解决方案,并可能引用示例中的代码。 注意事项部分需要提醒用户常见的陷阱,比如性能问题、数据倾斜、窗口范围设置错误等。特别是Hive处理大数据时的性能优化,比如合理分区和排序,避免全表扫描。这些内容能帮助用户避免实践中可能遇到的问题。相关问题部分需要生成与开窗函数相关的问题,引导用户进一步学习。比如与普通聚合函数的区别、性能优化、处理重复排名的方法、动态窗口应用等。这些问题应覆盖用户可能深入学习的各个方面,帮助他们巩固知识。最后,确保整个回答符合格式要求:行内公式用$...$,独立公式用$$...$$,正确的中文表达,引用标识自然添加。检查是否有遗漏的要点,比如是否覆盖了所有基本函数类型,语法是否解释清楚,示例是否易于理解等。同时,参考之前提供的引用内容,但用户的问题主要关于Hive,所以引用可能有限,需要确保内容准确可靠。</think># Hive开窗函数新手教程 ## 一、基础概念 开窗函数(Window Function)是Hive中用于在**数据窗口**内执行计算的特殊函数,核心特征是通过`OVER()`子句定义窗口范围。与聚合函数的区别在于: - 普通聚合函数:`SUM(x)`会将多行合并为单行结果 - 开窗函数:`SUM(x) OVER()`会保留原始行并添加计算结果 $$ \sum_{i=1}^{n} x_i \quad \text{vs} \quad \sum_{i=k}^{m} x_i \quad (k,m \in [1,n]) $$ ## 二、语法结构 ```sql 函数名([参数]) OVER ( [PARTITION BY 字段] [ORDER BY 字段 [ASC|DESC]] [ROWS BETWEEN 窗口范围] ) ``` ### 1. 核心子句解析 1. **PARTITION BY**:将数据划分为多个窗口(类似`GROUP BY`) ```sql -- 按部门分组计算 SUM(salary) OVER(PARTITION BY dept) ``` 2. **ORDER BY**:定义窗口内的排序规则 ```sql -- 按时间排序计算累计值 SUM(sales) OVER(ORDER BY sale_date) ``` 3. **窗口帧**:指定计算范围(默认`RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`) ```sql -- 最近3行移动平均 AVG(price) OVER(ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) ``` ## 三、常用函数示例 ### 1. 排名函数 ```sql SELECT employee_id, salary, ROW_NUMBER() OVER(ORDER BY salary DESC) as row_num, RANK() OVER(ORDER BY salary DESC) as rank, DENSE_RANK() OVER(ORDER BY salary DESC) as dense_rank FROM employee_table ``` 结果说明: | employee_id | salary | row_num | rank | dense_rank | |-------------|--------|---------|------|------------| | 101 | 8000 | 1 | 1 | 1 | | 102 | 7500 | 2 | 2 | 2 | | 103 | 7500 | 3 | 2 | 2 | ### 2. 聚合函数 ```sql SELECT product_id, sale_date, sales, SUM(sales) OVER(PARTITION BY product_id ORDER BY sale_date) as running_total FROM sales_table ``` ### 3. 分析函数 ```sql -- 计算与前一行的差值 SELECT time, value - LAG(value,1) OVER(ORDER BY time) as diff FROM metrics ``` ## 四、典型应用场景 1. **TopN分析**:通过`ROW_NUMBER()`实现分组Top3查询 ```sql SELECT * FROM ( SELECT *, ROW_NUMBER() OVER(PARTITION BY dept ORDER BY sales DESC) as rn FROM sales_data ) tmp WHERE rn <= 3 ``` 2. **累计计算**:使用`SUM() OVER(ORDER BY)`计算YTD累计值 3. **移动平均**:结合窗口帧计算近7天移动平均 ```sql AVG(price) OVER(ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) ``` ## 五、注意事项 1. **性能优化**: - 合理使用`PARTITION BY`字段,避免数据倾斜 - 优先使用`ROWS`替代`RANGE`(后者需要排序) 2. **窗口边界**:注意`UNBOUNDED PRECEDING`与`CURRENT ROW`的包含关系 3. **空值处理**:使用`COALESCE()`处理NULL值避免计算错误
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值