Hive数仓操作(十五)

Hive 开窗函数

Hive窗口函数是一种特殊的函数,允许用户在查询中对一组行进行计算,而不仅仅是单独的行。窗口函数可以在 SQL 查询中进行聚合、排名、累积计算等。这使得窗口函数在数据分析和报告生成中非常有用。

窗口函数的基本组成部分

  1. 函数类型 :如 ROW_NUMBER(), RANK(), DENSE_RANK(), SUM(), AVG() 等。
  2. OVER 子句:定义窗口的范围和分区,用于指定在哪些行上应用窗口函数。

窗口边界标识符

  1. CURRENT ROW:

    • 表示窗口的当前行。通常用于窗口的结束范围。
  2. n PRECEDING:

    • 表示当前行之前的n行。例如,ROWS BETWEEN 1 PRECEDING AND CURRENT ROW 表示从当前行向上看一行到当前行。
  3. n FOLLOWING:

    • 表示当前行之后的n行。例如,ROWS BETWEEN CURRENT ROW AND 2 FOLLOWING 表示从当前行到当前行的后两行。
  4. UNBOUNDED:

    • 表示没有边界,通常用于定义窗口的起点或终点。
  5. UNBOUNDED PRECEDING:

    • 表示从窗口的起点开始,不限行数。
  6. UNBOUNDED FOLLOWING:

    • 表示到窗口的终点结束,不限行数。

窗口边界函数

  1. LAG(col, n):

    • 这个函数用于获取当前行的前n行中的指定列的值。它可以用于比较当前行与前几行的数据。
    sql 复制代码
    SELECT 
        employee_id, 
        salary, 
        LAG(salary, 1) OVER (ORDER BY employee_id) AS previous_salary
    FROM 
        employees;

    这个示例显示了每个员工的当前工资和前一个员工的工资。

  2. LEAD(col, n):

    • 这个函数用于获取当前行的后n行中的指定列的值。与 LAG 类似,但它是向下查找。
    sql 复制代码
    SELECT 
        employee_id, 
        salary, 
        LEAD(salary, 1) OVER (ORDER BY employee_id) AS next_salary
    FROM 
        employees;

    这个示例显示了每个员工的当前工资和下一个员工的工资。

示例数据集

假设我们有一个名为 business 的表,内容如下:

name orderdate cost
Alice 2017-04-01 100
Bob 2017-04-05 150
Alice 2017-04-10 200
Charlie 2017-05-01 300
Bob 2017-05-10 100
Alice 2017-05-15 250
Charlie 2017-06-01 400

SQL 查询运行结果

1. 查询在2017年4月份购买过的顾客及总人数

sql 复制代码
SELECT name, COUNT(*) OVER() 
FROM business
WHERE SUBSTRING(orderdate, 1, 7) = '2017-04';

结果:

name COUNT(*)
Alice 3
Bob 3
Alice 3
2. 查询顾客的购买明细及月购买总额

顾客购买明细及购买总额:

sql 复制代码
SELECT name, orderdate, cost, SUM(cost) OVER() 
FROM business;

结果:

name orderdate cost SUM(cost)
Alice 2017-04-01 100 1300
Bob 2017-04-05 150 1300
Alice 2017-04-10 200 1300
Charlie 2017-05-01 300 1300
Bob 2017-05-10 100 1300
Alice 2017-05-15 250 1300
Charlie 2017-06-01 400 1300

明细及月购买总额:

sql 复制代码
SELECT name, orderdate, cost, SUM(cost) OVER(PARTITION BY MONTH(orderdate)) 
FROM business;

结果:

name orderdate cost SUM(cost)
Alice 2017-04-01 100 300
Bob 2017-04-05 150 300
Alice 2017-04-10 200 300
Charlie 2017-05-01 300 700
Bob 2017-05-10 100 700
Alice 2017-05-15 250 700
Charlie 2017-06-01 400 400

顾客购买明细及顾客购买总额:

sql 复制代码
SELECT name, orderdate, cost, SUM(cost) OVER(PARTITION BY name) 
FROM business;

结果:

name orderdate cost SUM(cost)
Alice 2017-04-01 100 550
Bob 2017-04-05 150 250
Alice 2017-04-10 200 550
Charlie 2017-05-01 300 700
Bob 2017-05-10 100 250
Alice 2017-05-15 250 550
Charlie 2017-06-01 400 400

顾客购买明细及顾客月购买总额:

sql 复制代码
SELECT name, orderdate, cost, SUM(cost) OVER(PARTITION BY name, MONTH(orderdate)) 
FROM business;

结果:

name orderdate cost SUM(cost)
Alice 2017-04-01 100 300
Bob 2017-04-05 150 150
Alice 2017-04-10 200 300
Charlie 2017-05-01 300 300
Bob 2017-05-10 100 100
Alice 2017-05-15 250 250
Charlie 2017-06-01 400 400
3. 按照日期进行累加

按照日期逐步累加购买总额

sql 复制代码
SELECT name, orderdate, cost,
SUM(cost) OVER(PARTITION BY name ORDER BY orderdate) 
FROM business;

方法2(边界从起点到当前行):

sql 复制代码
SELECT name, orderdate, cost,
SUM(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS sample4
FROM business;

结果:

name orderdate cost SUM(cost)
Alice 2017-04-01 100 100
Alice 2017-04-10 200 300
Alice 2017-05-15 250 550
Bob 2017-04-05 150 150
Bob 2017-05-10 100 250
Charlie 2017-05-01 300 300
Charlie 2017-06-01 400 700

当前行和前面一行的聚合:

sql 复制代码
SELECT name, orderdate, cost,
SUM(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN 1 PRECEDING AND CURRENT ROW) AS sample5
FROM business;

结果:

name orderdate cost sample5
Alice 2017-04-01 100 100
Alice 2017-04-10 200 300
Alice 2017-05-15 250 450
Bob 2017-04-05 150 150
Bob 2017-05-10 100 250
Charlie 2017-05-01 300 300
Charlie 2017-06-01 400 400

当前行和前后各一行的聚合:

sql 复制代码
SELECT name, orderdate, cost,
SUM(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS sample6
FROM business;

结果:

name orderdate cost sample6
Alice 2017-04-01 100 300
Alice 2017-04-10 200 550
Alice 2017-05-15 250 250
Bob 2017-04-05 150 250
Bob 2017-05-10 100 100
Charlie 2017-05-01 300 700
Charlie 2017-06-01 400 400

当前行及后面所有行:

sql 复制代码
SELECT name, orderdate, cost,
SUM(cost) OVER(PARTITION BY name ORDER BY orderdate ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) AS sample7
FROM business;

结果:

name orderdate cost sample7
Alice 2017-04-01 100 550
Alice 2017-04-10 200 250
Alice 2017-05-15 250 250
Bob 2017-04-05 150 100
Bob 2017-05-10 100 100
Charlie 2017-05-01 300 400
Charlie 2017-06-01 400 400
4. 查询顾客上次的购买时间

使用 LAG 函数:

sql 复制代码
SELECT name, orderdate, cost,
LAG(orderdate, 1) OVER(PARTITION BY name ORDER BY orderdate) AS last_purchase_date
FROM business;

结果:

name orderdate cost last_purchase_date
Alice 2017-04-01 100 NULL
Alice 2017-04-10 200 2017-04-01
Alice 2017-05-15 250 2017-04-10
Bob 2017-04-05 150 NULL
Bob 2017-05-10 100 2017-04-05
Charlie 2017-05-01 300 NULL
Charlie 2017-06-01 400 2017-05-01
相关推荐
森普智慧农业12 小时前
邛崃大梁酒庄:以酒旅融合赋能乡村振兴的示范样板
大数据·科技·生活·旅游
董可伦13 小时前
Spark 源码 | SparkSubmitArguments 参数解析(三)
大数据·分布式·spark
AIGS00113 小时前
突破语义鸿沟:从向量空间JBoltAI看企业大脑构建逻辑
java·大数据·人工智能·人工智能ai大模型应用
栋***t13 小时前
2026金融、政务等高数据安全与合规行业的在线考试系统选型之道
大数据·金融·开源软件·政务·无纸化
珠海西格电力13 小时前
西格电力零碳园区管理系统:核心功能全解析,赋能园区低碳智能化落地
大数据·运维·网络·人工智能·信息可视化·能源
深盾科技_Virbox13 小时前
软件授权工具静默安装实践
java·运维·数据库·安全·软件需求
延凡科技14 小时前
延凡科技综合监控预警处置平台—— 一体化视频AI安防闭环系统设计与功能实现[特殊字符]️
数据库·人工智能·科技·安全·能源
老马聊技术14 小时前
Rocky Linux 9.0 安装 MySQL8.x详细教程
linux·数据库
CoreTK芯通康EMC整改14 小时前
Type-C 高速接口 ESD 失效深度解析:器件选型 + PCB 布局双重解决方案
大数据·网络·emc·芯通康·pcb电磁兼容
醇氧14 小时前
主流 Agent 开发框架全解析(2026 最新)
大数据·数据库·人工智能·开源