Hive学习——开窗函数精讲

news2025/7/21 21:40:55

目录

一、基于行的窗口函数——行的起点~行的终点

二、基于值的窗口函数——值的起点~值的终点

三、基于分区的窗口函数

四、基于缺省的窗口函数

五、lead与lag

六、first_value和last_value

七、排名函数——rank(113)、dense_rank(112)、row_number(123)

八、NTILE分桶

九、窗口函数练习题

(一)练习一

1.统计每个用户截至每次下单的累积下单总额

2.统计每个用户截至每次下单的当月累积下单总额

3.统计每个用户每次下单距离上次下单相隔的天数(首次下单按0天算)

4.查询所有下单记录以及每个用户的每个下单记录所在月份的首/末次下单日期

5.为每个用户的所有下单记录按照订单金额进行排名

(二)练习二

1.查询所有用户的下单次数

2.查询每个用户下单的次数

3.查询每个用户下单总额

4.查询每个用户每月下单总额

5.每个人截止到当前日期所下订单总额——每天的累加和

6.rows between and用法

7.ntile用例


一、基于行的窗口函数——行的起点~行的终点

注意:between and中间不同颜色的关键词,对应and后面颜色的关键词,且只能在对应颜色范围内选择and后面是什么关键词!

between 后面是起点行:

        起点位于当前行之前:

         unbounded preceding:负无穷,整个表的第一行

         [num] preceding:当前行的前num行,起点[num] preceding>=终点[num] preceding

                                             例如:前面5行作为起点,前面2行作为终点是可行的;

                                                         前面2行作为起点,前面5行作为终点是不可行的

        起点位于当前行:

                current row:当前行

        起点位于当前行之后:

              [num] following:当前行的后num行,起点[num] following<=终点[num] following

                                            例如:后面5行作为起点,后面2行作为终点是不可行的;

                                                       后面2行作为起点,后面5行作为终点是可行的

and后面是终点行:

        终点位于当前行之前:

                [num] preceding

                current row

                [num] following

                unbounded following:正无穷,整个表的最后一行

        终点位于当前行:

                current row        

                [num] following

                unbounded following

        终点位于当前行之后:

                [num] following

                unbounded following

计算历史截止到当前的销售额(不区分user_id):

二、基于值的窗口函数——值的起点~值的终点

上图单词的含义由行变为值即可,关键词选取规则与行的规则相同,此处省略。

order by [column]:基于行中的order by是指定行的顺序,只有在每行的顺序固定的前提下,对每行进行聚合才是有意义的。基于值的order by目的不是排序,而是比表名基于哪个字段的值来划分窗口。

        当窗口是[num] preceding或[num] following来定义时:

order by指定的column必须是[整数]型,才能够进行num的加减!窗口不涉及到加减num的操作,column字段类型随意。字符串按照字符大小比较。

between 后面是起点行:

        起点位于当前值之前:

         unbounded preceding:负无穷,第一行某个字段的值

         [num] preceding:当前值的减去num

        起点位于当前行:

                current row:当前字段对应的值

        起点位于当前行之后:

              [num] following:当前值的加上num

and后面是终点行:

        终点位于当前值之前:

                [num] preceding

                current row

                [num] following

                unbounded following:正无穷,最后一行某个字段的值

        终点位于当前行:

                current row        

                [num] following

                unbounded following

        终点位于当前行之后:

                [num] following

                unbounded following

统计截止到每个下单日期的销售额(注意下单日期相同的也要相加)

三、基于分区的窗口函数

每个用户,截止到每次下单时,历史下单总额

四、基于缺省的窗口函数

五、lead与lag

功能:获取当前行的上、下边某行、某个字段的值。

注意:lead和lag不支持自定义窗口。没有range between and和rows between and。

只需考虑在取行数时是否需要分区和排序。

统计每一次下单记录的 上一次和下一次的下单日期,从而计算每次下单的时间间隔

六、first_value和last_value

功能:获取窗口内某一列的第一个值/最后一个值,需要指定字段。

boolean:是否要跳过null值,如果first_value第一行是null值,true就跳过,找下一行;false就不跳过,返回null值;last_value的boolean最后一行是null值是否跳过。

七、排名函数——rank(113)、dense_rank(112)、row_number(123)

注意:排名函数也不支持自定义窗口。

八、NTILE分桶

NTILE(n),用于将分组数据按照顺序切分成n片,返回当前切片值。

如果切片不均匀,默认增加第一个切片的分布

查询想要每位顾客购买金额前1/3的交易记录 

select t.name, order_date, cost
from (
         select name,
                order_date,
                cost,
                ntile(3) over (partition by name order by cost desc) as rk
         from t_window) t
where t.rk = 1;

 

九、窗口函数练习题

(一)练习一

-- 数据源

create table order_info
(
    order_id     string, --订单id
    user_id      string, -- 用户id
    user_name    string, -- 用户姓名
    order_date   string, -- 下单日期
    order_amount int     -- 订单金额
);

insert overwrite table order_info
values ('1', '1001', '小元', '2022-01-01', '10'),
       ('2', '1002', '小海', '2022-01-02', '15'),
       ('3', '1001', '小元', '2022-02-03', '23'),
       ('4', '1002', '小海', '2022-01-04', '29'),
       ('5', '1001', '小元', '2022-01-05', '46'),
       ('6', '1001', '小元', '2022-04-06', '42'),
       ('7', '1002', '小海', '2022-01-07', '50'),
       ('8', '1001', '小元', '2022-01-08', '50'),
       ('9', '1003', '小辉', '2022-04-08', '62'),
       ('10', '1003', '小辉', '2022-04-09', '62'),
       ('11', '1004', '小猛', '2022-05-10', '12'),
       ('12', '1003', '小辉', '2022-04-11', '75'),
       ('13', '1004', '小猛', '2022-06-12', '80'),
       ('14', '1003', '小辉', '2022-04-13', '94');

1.统计每个用户截至每次下单的累积下单总额

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       sum(order_amount) over (partition by user_id order by order_date
           rows between unbounded preceding and current row ) sum_so_far
from order_info;

2.统计每个用户截至每次下单的当月累积下单总额

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       sum(order_amount) over (partition by user_id ,month(order_date) order by order_date
           rows between unbounded preceding and current row ) sum_so_far
from order_info;

3.统计每个用户每次下单距离上次下单相隔的天数(首次下单按0天算)

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       datediff(order_date, (lag(order_date, 1, order_date) over
           (partition by user_id order by order_date))) as diff
from order_info;

4.查询所有下单记录以及每个用户的每个下单记录所在月份的首/末次下单日期

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       first_value(order_date) over-- 不需要管理null值,默认false
           (partition by user_id ,substring(order_date, 1, 7) order by order_date) as first_date,
       last_value(order_date) over
           (partition by user_id ,substring(order_date, 1, 7) order by order_date
           rows between unbounded preceding and unbounded following)               as last_date
from order_info;

注意:这里选取每月最后一次下单日期需要考虑正无穷,选取每月第一次下单日期的rows between and可写可不写。

5.为每个用户的所有下单记录按照订单金额进行排名

select order_id,
       user_id,
       user_name,
       order_date,
       order_amount,
       -- 注意排名函数的()内没有值
       rank() over (partition by user_id order by order_amount desc ) as rk,
       dense_rank() over (partition by user_id order by order_amount desc ) as drk,
       row_number() over (partition by user_id order by order_amount desc ) as rn
from order_info;

(二)练习二

数据源——t_window表

1.查询所有用户的下单次数

select name, count(*) over ()
from t_window
where substring(order_date, 1, 7) = '2015-04';

-- 对名字进行去重的两种方法
select distinct name,
                count(*) over ()
from t_window
where substring(order_date, 1, 7) = '2015-04';

select name,
       count(*) over ()
from t_window
where substring(order_date, 1, 7) = '2015-04'
group by name;

2.查询每个用户下单的次数

select distinct name,
                count(*) over (partition by name) as num
from t_window
where substring(order_date, 1, 7) = '2015-04';

 

3.查询每个用户下单总额

select name, order_date, cost, sum(cost) over (partition by name) cost_sum
from t_window;

 

4.查询每个用户每月下单总额

-- order by之前

select 
    name, 
    order_date, 
    cost, 
    sum(cost) over (partition by month(order_date))
from t_window;

-- order by之后

select name,
       order_date,
       cost,
       sum(cost) over
           (partition by month(order_date) order by order_date)
from t_window;

 

5.每个人截止到当前日期所下订单总额——每天的累加和

select 
    name, 
    order_date, 
    cost, 
    sum(cost) over (partition by name order by order_date)
from t_window;

 

6.rows between and用法

select name
     , order_date
     , cost
     , sum(cost) over ()                                                                                         as row1-- 全表数据cost的总和,661
     , sum(cost) over (partition by name)                                                                        as row2-- 个人累计消费总和
     , sum(cost) over (partition by name order by order_date rows between unbounded preceding and unbounded following) as row22
     , sum(cost) over (partition by name order by order_date)                                                    as row3-- 个人截止当前日期累计消费总和
     , sum(cost) over (partition by name order by order_date rows between unbounded preceding and current row )  as row4-- 效果同row3
     , sum(cost) over (partition by name order by order_date rows between 1 preceding and current row )          as row5-- 当前消费额与上一次消费额的总和
     , sum(cost) over (partition by name order by order_date rows between 1 preceding and 1 following )          as row6-- 上一次和下一次的消费总和
     , sum(cost) over (partition by name order by order_date rows between current row and unbounded following)   as row7-- 当前消费到最后一次消费总和
     , sum(cost) over (partition by name order by order_date rows between current row and 3 following)           as row8-- 距离当前日期最近的后三次消费总和
from t_window;

 

7.ntile用例

select name
     , order_date
     , cost
     , ntile(3) over ()                                      as row1
     , ntile(3) over (partition by name)                     as row2-- mark 四条数据,4%3=1,多出来的一条又回到第一
--        ,ntile(3) over (order by order_date) as row3-- 排完序以后再切片
     , ntile(3) over (order by name)                         as row3-- 按照name的首字母进行排序
     , ntile(3) over (partition by name order by cost desc ) as rows4
from t_window;

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/368547.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nvm (node版本管理工具)安装的详细步骤,并解决安装过程中遇到的问题

1、下载NVM&#xff0c;跳转下载链接后&#xff0c;如下图&#xff0c;下载红框后解压文件 2、安装 注意&#xff1a;双击安装之后&#xff0c;会有两个地址选择&#xff0c; 1、地址中不能存在空格 2、不要放在C盘中&#xff0c;后面需要改个设置文件&#xff0c;安装到C盘的…

银行家算法

银行家算法 银行家算法是一种用来避免操作系统死锁出现的有效算法&#xff0c;所以在引入银行家算法的解释之前&#xff0c;有必要简单介绍一下死锁的概念。 一、死锁 死锁&#xff1a;是指两个或两个以上的进程在执行过程中&#xff0c;由于竞争资源或者由于彼此通信而造成…

Gitlab Linux 环境安装

环境检查是否已经安装了gitlab&#xff0c;安装了需要卸载# 检查当前环境是否已经安装了gitlab&#xff0c;并且查看版本 gitlab-rails console # 删除命令 yum remove git# 查找命令 rpm -qa | grep gitlab # 删除命令 rpm -e gitlab-ce-12.10.1-ce.0.el8.x86_64 # 查找命令f…

DS期末复习卷(八)

一、选择题(30分) 1.字符串的长度是指&#xff08; C &#xff09;。 (A) 串中不同字符的个数 (B) 串中不同字母的个数 (C ) 串中所含字符的个数 (D) 串中不同数字的个数 2.建立一个长度为n的有序单链表的时间复杂度为&#xff08; C &#xff09; (A) O(n) (B) O(1) © …

小米/红米手机数据恢复:从小米手机恢复已删除的数据

如果您不小心删除了小米手机上的数据&#xff0c;后来发现您需要它&#xff0c;那么本文适合您。我将向您介绍一些最可靠的小米恢复方法&#xff0c;以将您的数据恢复到您的设备上。无论您是否有备份&#xff0c;都可以处理。让我们开始吧&#xff01; 小米数据恢复 - 如何做&a…

一篇学习JVM

基础入门 1.JDK、JRE、JVM三者间的联系与区别 JDK JDK(Java SE Development Kit)&#xff0c;Java标准开发包&#xff0c;它提供了编译、运行Java程序所需的各种工具和资源&#xff0c;包括Java编译器、Java运行时环境&#xff0c;以及常用的Java类库等。 下图是JDK的安装目…

博客管理系统--项目说明

项目体验地址&#xff08;账号&#xff1a;123&#xff0c;密码&#xff1a;123&#xff09;http://120.53.20.213:8080/blog_system/login.html项目码云Gitee地址&#xff1a;https://gitee.com/GoodManSS/project/tree/master/blog_system&#xff08;一&#xff09;准备工作…

【ArcGIS Pro二次开发】(7):地图(Map)的基本操作

地图是ArcGIS Pro中的基础起点&#xff0c;也是大多数工程的基础。主要用于显示表示空间数据的图层。 一、地图(Map)的基本操作示例 1、获取当前地图 var map MapView.Active.Map; 2、获取一级图层 var lys map.Layers; 用于获取地图中的单一图层&#xff0c;以及图层组…

【正点原子FPGA连载】第十六章DP彩条显示实验 摘自【正点原子】DFZU2EG_4EV MPSoC之嵌入式Vitis开发指南

1&#xff09;实验平台&#xff1a;正点原子MPSoC开发板 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id692450874670 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html 第十六章DP彩条显…

什么是路由?

什么是路由&#xff1f; 介绍 **路由是指路由器从一个接口上收到数据包&#xff0c;根据数据包的目的地址进行定向并转发到另一个接口的过程。**路由发生在OSI网络参考模型中的第三层即网络层。 路由引导分组转送&#xff0c;经过一些中间的节点后&#xff0c;到它们最后的目…

六【 SpringMVC框架】

一 SpringMVC框架 目录一 SpringMVC框架1.什么是MVC2.SpringMVC概述3.SpringMVC常见开发方式4.SpringMVC执行流程5.SpringMVC核心组件介绍6.快速构建Spring MVC程序✅作者简介&#xff1a;Java-小白后端开发者 &#x1f96d;公认外号&#xff1a;球场上的黑曼巴 &#x1f34e;个…

工业三防平板可应用于各种复杂苛刻的工作环境

伴随着工业互联网技术的快速发展&#xff0c;生产制造自然环境繁杂&#xff0c;机器设备规定比较严苛。普通平板在工业场景户外场景等都比较容易出现磕碰或者出现其它因素如进水、进灰尘而引发设备故障。三防平板之所以在建筑工程的应用较为广泛&#xff0c;这与其独特的性能是…

线性数据结构:数组 Array

一、前言数组是数据结构还是数据类型&#xff1f;数组只是个名称&#xff0c;它可以描述一组操作&#xff0c;也可以命名这组操作。数组的数据操作&#xff0c;是通过 idx->val 的方式来处理。它不是具体要求内存上要存储着连续的数据才叫数组&#xff0c;而是说&#xff0c…

scratch和平使者 电子学会图形化编程scratch等级考试一级真题和答案解析2022年12月

目录 scratch和平使者 一、题目要求 1、准备工作 2、功能实现 二、案例分析

视图、游标、慢查询日志

Java知识点总结&#xff1a;想看的可以从这里进入 目录2.7、视图、游标2.7.1、视图2.7.2、游标2.7、慢查询日志2.7、视图、游标 2.7.1、视图 视图是一种虚拟存在的表&#xff0c;同真实表一样&#xff0c;视图也由列和行构成&#xff0c;它不存在于数据库中&#xff0c;是我们…

【红黑树】红黑树插入操作相关的细节和疑难拆解分析

本文就红黑树的插入操作进行细致到每一个小步骤的解析。1&#xff0c;成员变量本红黑树使用了三叉链结构&#xff0c;使用的时候尤其要记得处理指向父亲的指针。为何在节点的构造函数中&#xff0c;默认节点的颜色为红色&#xff1f;因为考虑到红黑树的性质&#xff08;对于每个…

汇编语言 标志位总结

缩写原意: Overflow of = OV NV [No Overflow] Direction df = DN (decrement) UP (increment) Interrupt if = EI (enabled) DI (disabled) Sign sf = NG (negative) PL (positive) Zero zf = ZR [zero] NZ [ Not zero] Auxiliary Carry af = AC NA [ No AC ] Parity pf = PE…

计网个人作业05

R1 链路层可以提供如下服务 链路层服务IP能否提供&#xff1f;TCP能否提供&#xff1f;流量控制✔差错检测✔✔差错纠正全双工、半双工✔ R2 不冗余 IP层有丢包的情况⼀个⻓的 TCP 报⽂段会被分⽚成多个 IP 数据报形成不同的帧&#xff0c;不同的帧可能会被不同链路传输。同…

二.线性表之顺序表

文章目录前言一.顺序表的概念及结构二.顺序表的接口实现1.顺序表的动态存储2.顺序表的初始化3.顺序表尾插#封装&#xff1a;扩容函数4.顺序表尾删5.顺序表头插6.顺序表头删7.顺序表查找8.顺序表在pos位置插入x9.顺序表删除pos位置的值10.顺序表销毁11.顺序表打印三.源1.Seqlist…

3000字,聊一聊学习低代码和学习编程到底有什么区别?

作者介绍胡艳平&#xff0c;万应低代码联合创始人、CTO&#xff0c;中国信通院低代码/无代码推进中心技术专家&#xff0c;全国信标委《低代码开发平台能力要求》起草人之一。曾有科技公司CTO问我&#xff1a;低代码是不是一种不用敲代码的编程语言&#xff1f;在不确定低代码能…