HiveSQL题——炸裂函数(explodeposexplode)

目录

一、炸裂函数的知识点

1.1?炸裂函数

?explode?

posexplode

1.2 lateral view 侧写视图

二、实际案例

2.1 每个学生及其成绩

0 问题描述

1 数据准备

2 数据分析

3 小结

2.2?日期交叉问题

0 问题描述

1 数据准备

2 数据分析

3 小结

2.3?用户消费金额

0 问题描述

1 数据准备

2 数据分析

3 小结


一、炸裂函数的知识点

炸裂函数(一行变多行)本质属于UDTF函数(接收一行数据,输出一行或者多行数据)。

1.1炸裂函数

1.2 lateral view 侧写视图

官网链接:LanguageManual LateralView - Apache Hive - Apache Software Foundation

  • 定义:lateral view 通常与UDTF配合使用,侧视图的原理是将UDTF的结果构建成一个类似于视图的表,再将原表中的每一行和UDTF函数输出的每一行进行连接,生成一张新的虚拟表。
  • 举例:select id, name, hobbies, hobby from person lateral view explode(hobbies) tmp as hobby; 代码分析: 对原表person中的hobbies列进行炸裂(一行变多行),利用侧视图lateral view对该UDTF产生的记录设置字段名称为hobby,再将原表中person的一每行与hobby进行连接形成一个虚拟表,命名为tmp。
  • 注意:使用lateral view时侧写视图时,可以对UDTF产生的记录设置字段名称,上述例子为hobby,产生的hobby字段可以用于group by、order by 、limit等语句中,不需要再单独嵌套一层子查询

二、实际案例

2.1 每个学生及其成绩

0 问题描述

根据学生成绩表,计算学生的成绩。

1 数据准备
create table if not exists table10
(class    string comment '班级名称',student string comment '学生名称',score   string comment '学生分数'
)comment '学生成绩表';
INSERT overwrite table table10
VALUES ("1班","小A,小B,小C","80,92,70"),("2班","小D,小E","88,62"),("3班","小F,小G,小H","90,97,85");
2 数据分析

思路一:lateral view + explode

selectclass,student,score,student_name,student_score
from table10 lateral view explode(split(student, ',')) tmp1 as student_namelateral view explode(split(score, ',')) tmp2 as student_score;

**bug:**上面逻辑能跑通,但是学生姓名和学生成绩对应不上,出现错乱,弃用。

正确的代码如下:

思路二: lateral view + posexplode

selectclass,student,score,student_name,student_score
from table10 lateral view posexplode(split(student, ',')) tmp3 as student_index_st, student_namelateral view posexplode(split(score, ',')) tmp4 as student_index_sc, student_score
where student_index_st = student_index_sc;

说明:student_index_st = student_index_sc 的作用:下角标对齐,实现学生和成绩一一对应

3 小结

上述案例的学生成绩表中,【学生姓名】字段和【学生成绩】都是数组类型的字符串,我们需要对两个字段分别炸裂后,实现每个学生与其成绩一一对应,因此需要借助posexlode函数的pos下角标进行约束。(用explode函数无法实现)

2.2日期交叉问题

0 问题描述

统计每个品牌的总营销天数(营销日期有重叠的地方需要去重

1 数据准备
create table promotion_info
(promotion_id string comment '优惠活动id',brand        string comment '优惠品牌',start_date   string comment '优惠活动开始日期',end_date     string comment '优惠活动结束日期'
) comment '各品牌活动周期表';insert overwrite table promotion_info
values (1, 'oppo', '2021-06-05', '2021-06-09'),(2, 'oppo', '2021-06-11', '2021-06-21'),(3, 'vivo', '2021-06-05', '2021-06-15'),(4, 'vivo', '2021-06-09', '2021-06-21'),(5, 'redmi', '2021-06-05', '2021-06-21'),(6, 'redmi', '2021-06-09', '2021-06-15'),(7, 'redmi', '2021-06-17', '2021-06-26'),(8, 'huawei', '2021-06-05', '2021-06-26'),(9, 'huawei', '2021-06-09', '2021-06-15'),(10, 'huawei', '2021-06-17', '2021-06-21');
2 数据分析

思路一:用带有下标的炸裂函数posexplode将活动区间炸裂成具体的每一天的日期。即:将同一个品牌的所有活动日期都有列出来,再对重叠的日期进行统一去重

select brand,count(distinct event_date)from
(selectpromotion_id,brand,start_date,-- 用 start_date + 下角标pos date_add(start_date,pos) as event_date,pos
from (selectpromotion_id,brand,start_date,end_date,split(space(datediff(end_date, start_date)), '') as arfrom promotion_info) tmp1lateral view posexplode(ar) tmp2 as pos, item
)tmp2
group by brand;

思路一的代码拆解分析:

以一条数据为例,promotion_id      brand       start_date       end_date1             'oppo'     '2021-06-05'    '2021-06-09'
(1)  split(space(datediff(end_date, start_date)), '') as diff 的结果:根据[9-5]=4,利用space函数生成长度是4的空格字符串,再利用split函数切割1 (promotion_id) , 'oppo'(brand) , '2021-06-05'(start_date) ,'2021-06-09'(end_date) ,  diff ["","","","",""](2)用posexplode经过转换增加行(列转行,炸裂),通过下角标pos来获取 event_date,根据数组["","","","",""],得到pos的取值是0,1,2,3,4炸裂得出下面五行数据(一行变五行)1,oppo,2021-06-05(start_date),2021-06-05= date_add(2021-06-05,0) (event_date= start_date+pos)1,oppo,2021-06-05(start_date),2021-06-06= date_add(2021-06-05,1) (event_date= start_date+pos)1,oppo,2021-06-05(start_date),2021-06-07 = date_add(2021-06-05,2) (event_date= start_date+pos)1,oppo,2021-06-05(start_date),2021-06-07 = date_add(2021-06-05,3) (event_date= start_date+pos)1,oppo,2021-06-05(start_date),2021-06-08 = date_add(2021-06-05,4) (event_date= start_date+pos)1,oppo,2021-06-05(start_date),2021-06-09 = date_add(2021-06-05,5) (event_date= start_date+pos)
炸裂的目的:活动的优惠时间段[ '2021-06-05' ,  '2021-06-09' ] 拆分成具体的
每一天event_date:'2021-06-05','2021-06-06','2021-06-07','2021-06-08','2021-06-09'
(3)根据品牌brand进行分组,求count(distinct event_date) ,从而得到每品牌的总营销天数(营销日期有重叠的地方已经去重了)

思路二:用带有下标的炸裂函数posexplode

select brand,count(distinct event_date)from
(selectpromotion_id,brand,start_date,date_add(start_date,pos) as event_date,pos
from (selectpromotion_id,brand,start_date,end_date,split(repeat(',',datediff(end_date, start_date)),',') as arfrom promotion_info) tmp1lateral view posexplode(ar) tmp2 as pos, item
)tmp2
group by brand;

思路二的代码拆解分析:跟思路一的逻辑基本是一样的 ,区别仅在于:用代码 split(repeat(‘,’,datediff(end_date, start_date)),‘,’) as ar 去替换 split(space(datediff(end_date, start_date)), ‘’) as ar

思路三的代码逻辑如下:

selectbrand,--对品牌brand分组求sum的原因:同一个用户可能对应多段不交叉的活动sum(datediff(end_date, new_start_date) + 1) days 
from (selectbrand,new_start_date,end_datefrom (selectbrand,--判断逻辑:1.如果max_end_date是null(意味着当前行就是首行,不存在上一行了),直接取start_date--2.如果max_end_date不是null,进一步判断【当前行】的start_date与max_end_date的大小,如果start_date小,那用max_date+ 1的值作为【当前行】的新new_start_dateif(max_end_date is null, start_date,if(start_date > max_end_date, start_date, date_add(max_end_date, 1))) new_start_date,end_datefrom (selectbrand,start_date,end_date,-- 开窗范围:同一个品牌内部:上无边界到截止到上一行-- 开窗的计算逻辑:max(end_date)  --> 对【上无边界到上一行】的最大结束时间end_date进行标记,再与当前行的起始时间start_date进行比对max(end_date)over (partition by brand order by start_date rows between unbounded preceding and 1 preceding) max_end_datefrom promotion_info) t1) t2-- 需要保证每行数据的新的起始时间new_start_date 比 结束时间end_date 小where new_start_date < end_date) t3
group by brand;

思路三:没有用到炸裂函数,关键思想是:当活动的上一个日期区间A 与 当前的日期区间B出现重叠(日期交叉,有重复数据)时,需要将区间B的起始时间改成区间A的结束时间。(修改之后需要保证B区间的结束时间> 开始时间)

3 小结

上述代码中用到的函数有:

一、字符串函数1、空格字符串函数:space语法:space(int n)返回值:string说明:返回值是n的空格字符串举例:select length (space(10)) --> 10一般space函数和split函数结合使用:select split(space(3),'');  -->   ["","","",""]2、split函数(分割字符串)语法:split(string str,string pat)返回值:array说明:按照pat字符串分割str,会返回分割后的字符串数组举例:select split ('abcdf','c') from test; -> ["ab","df"]3、repeat:重复字符串语法:repeat(string A, int n)返回值:string说明:将字符串A重复n遍。举例:select repeat('123', 3); -> 123123123一般repeat函数和split函数结合使用:select split(repeat(',',4),',');  -->  ["","","","",""]二、炸裂函数explode 语法:lateral view explode(split(a,',')) tmp  as new_column返回值:string说明:按照分隔符切割字符串,并将数组中内容炸裂成多行字符串举例:select student_score from test lateral view explode(split(student_score,',')) 
tmp as student_scoreposexplode语法:lateral view posexploed(split(a,',')) tmp as pos,item 返回值:string说明:按照分隔符切割字符串,并将数组中内容炸裂成多行字符串(炸裂具备瞎下角标 0,1,2,3)举例:select student_name, student_score from testlateral view posexplode(split(student_name,',')) tmp1 as student_name_index,student_namelateral view posexplode(split(student_score,',')) tmp2 as student_score_index,student_scorewhere student_score_index = student_name_index

2.3用户消费金额

0 问题描述

变更需求:table11表的第1,4列不表,第2列需要变更为连续日期,第3列需要变更成【截止当月的累积消费额】

1 数据准备
create table if not exists table11
(user_id  string comment '用户标识',dt       string comment '消费日期',price    string comment '消费金额',qs       int comment '用户应存期数'
)comment '用户消费详情表';
INSERT overwrite table table11
VALUES ("A","2018-12-21","9439.30",12),("A","2019-03-21","9439.30",12),("A","2019-06-21","9439.30",12),("A","2019-09-21","9439.30",12),("B","2018-12-02","9439.30",10),("B","2019-02-02","9439.30",10),("B","2019-06-02","9439.30",10);
2 数据分析
-- 思路一:利用posexplode函数进行炸裂,同时生成下角标pos,
--将消费区间(一行)炸裂成多行
selecttmp3.user_id,tmp3.event_dt,-- sum() over(partition by .. order by .. ) 窗口计算的范围是:上无边界(起始行)到当前行,求消费金额的累积值(order by 后面没有窗口子句的情况下,窗口范围是:上无边界(起始行)到当前行)cast(sum(tmp4.price) over (partition by tmp3.user_id order by tmp3.event_dt) as decimal(18, 2)) as price,tmp3.max_qs
from (selectuser_id,add_months(min_dt, pos) as event_dt,max_qs,posfrom (selectuser_id,min(dt ) as min_dt,max(price) max_price,max(qs)    max_qsfrom table11group by user_id) tmp1 lateral view posexplode(split(space(max_qs), '')) tmp2 as pos, item) tmp3left join (selectuser_id,dt,pricefrom table11) tmp4on tmp3.user_id = tmp4.user_id and tmp3.event_dt= tmp4.dt;
3 小结

利用posexplode的下角标pos进行填补连续。利用sum(price)over(partition by …order by)进行消费金额的累积值统计(截止到当日)

(1)lateral view posexplode(split(space(max_qs), ‘’)) tmp2 as pos, item;–>对字段 期数ds进行posexplode炸裂,一行变多行,且生成对应的下角标pos

(2)add_months(min_ds, pos) as new_ds; --> 基于min_dt+ pos对消费日期 进行填补,组成连续的消费日期区间。

待补充:**炸裂的弊端是可能会发生数据膨胀,**当数据集小的时候,用炸裂方便,当时数据集大时,需慎用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从差分电容到多轴测量:解读 BendLabs 柔性弯曲传感器核心技术

BendLabs是一家技术公司&#xff0c;致力于通过灵活的软传感解决方案将运动测量和理解带给世界。BendLabs柔性弯曲传感器由医用级有机硅制成&#xff0c;能够满足精确、多轴、柔软、灵活的传感需求。BendLabs柔性弯曲传感器采用差分电容原理&#xff0c;具有高精度、低功耗、无…

【数字电路与逻辑设计】实验二 数值比较器

文章总览&#xff1a;YuanDaiMa2048博客文章总览 【数字电路与逻辑设计】实验二 数值比较器 一、实验内容二、设计过程&#xff08;一&#xff09;真值表&#xff08;二&#xff09;设计思路 三、源代码&#xff08;一&#xff09;代码说明&#xff1a;&#xff08;二&#xff…

39 vector深入理解 · 迭代器失效深度浅拷贝

目录 一、迭代器失效 &#xff08;一&#xff09;外部迭代器失效 1、扩容引起的野指针问题 2、删除引起的逻辑问题 二、深度浅拷贝 一、迭代器失效 迭代器可以理解为像指针一样的类对象&#xff0c;但不要一味地认为迭代器就是指针&#xff0c;指针可以实现迭代器&#xff…

2024年认证杯SPSSPRO杯数学建模C题(第一阶段)云中的海盐解题全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 C题 云中的海盐 原题再现&#xff1a; 巴黎气候协定提出的目标是&#xff1a;在2100年前&#xff0c;把全球平均气温相对于工业革命以前的气温升幅控制在不超过2摄氏度的水平&#xff0c;并为1.5摄氏度而努力。但事实上&#xff0c;许多之前的…

AI智能体Prompt预设词指令大全+GPTs应用使用

AI智能体使用指南 直接复制在AI工具助手中使用&#xff08;提问前&#xff09; 可前往SparkAi系统用户官网进行直接使用 SparkAI系统介绍文档&#xff1a;Docs 常见AI智能体GPTs应用大全在线使用 自定义添加制作AI智能体进行使用&#xff1a; 文章润色器 你是一位具有敏锐洞察…

Origin快速拟合荧光寿命、PL Decay (TRPL)数据分析处理-方法二

1.先导入数据到origin 2.导入文件的时候注意&#xff1a;名字短的这个是&#xff0c;或者你打开后看哪个里面有800&#xff0c;因为我的激光重频是1.25Hz&#xff08;应该是&#xff0c;不太确定单位是KHz还是MHz&#xff09;&#xff0c;所以对应的时间是800s。 3.选中两列直接…

Mybatis框架进阶(标签)

1. <if>标签 DROP DATABASE IF EXISTS mybatis_test; CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4; use mybatis_test;DROP TABLE IF EXISTS user_info; CREATE TABLE user_info (id INT ( 11 ) NOT NULL AUTO_INCREMENT,username VARCHAR ( 127 ) NOT…

【知识点】图与图论入门

何为图论 见名知意&#xff0c;图论 (Graph Theory) 就是研究 图 (Graph) 的数学理论和方法。图是一种抽象的数据结构&#xff0c;由 节点 (Node) 和 连接这些节点的 边 (Edge) 组成。图论在计算机科学、网络分析、物流、社会网络分析等领域有广泛的应用。 如下&#xff0c;这…

泷羽sec-burp(4)burp常见用法 以及 漏洞测试理论 学习笔记

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

Linux上传代码的步骤与注意事项

最近因为工作需要&#xff0c;要上传代码到 DPDK 上&#xff0c;代码已经上传成功&#xff0c;记录一下过程&#xff0c;给大家提供一个参考。我这次需要上传的是pmd&#xff0c;即poll mode driver。 1 Coding Style 要上传代码&#xff0c;第一件事就是需要知道Coding Styl…

vllm0.5.0的v1/completions各参数说明

一、调用示例 curl -X POST \http://ip:8001/v1/completions \-H accept: application/json \-H Content-Type: application/json \-d {"model": "qwen-api","prompt": ["讲个中文笑话"],"best_of": 1,"n": 1,&qu…

Java项目实战II基于微信小程序的作品集展示(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着移动互联网技术的飞速…

物联网入门-Arduino的下载与配置教程(以ESP32为例)-2024

教程介绍 本次教程主要讲述如何下载与配置Arduino&#xff0c;以及开发版对应驱动的下载安装 原文链接&#xff1a;物联网入门-Arduino的下载与配置教程(以ESP32为例)-2024 步骤概述 1&#xff1a;下载Arduino 2&#xff1a;安装Arduino 3&#xff1a;下载安装驱动 4&am…

13.在 Vue 3 中使用OpenLayers加载鹰眼控件示例教程

在 WebGIS 开发中&#xff0c;鹰眼控件 是一个常用的功能&#xff0c;它可以为用户提供当前地图位置的概览&#xff0c;帮助更好地定位和导航。在本文中&#xff0c;我们将基于 Vue 3 的 Composition API 和 OpenLayers&#xff0c;创建一个简单的鹰眼控件示例。 效果预览 在最…

Flink如何基于数据版本使用最新离线数据

业务场景 假设批量有一张商户表&#xff0c;表字段中有商户名称和商户分类两个字段。 批量需要将最新的商户名称和分类的映射关系推到hbase供实时使用。 原实现方案 a.原方案内容 为解决批量晚批问题&#xff0c;批量推送hbase表时一份数据产生两类rowkey&#xff1a;T-1和…

从GCC源码分析C语言编译原理——源码表层分析(脚本篇)

目录 一、目录结构 二、有意思的小功能 三、install脚本 脚本变量和设置 程序名称变量 模式和命令 参数解析 主要逻辑 四、主要功能脚本 ------------------------------------------------------------------------------------------------------------------------…

Latex转word(docx)或者说PDF转word 一个相对靠谱的方式

0. 前言 投文章过程中总会有各种各样的要求&#xff0c;其中提供word格式的手稿往往是令我头疼的一件事。尤其在多公式的文章中&#xff0c;其中公式转换是一个头疼的地方&#xff0c;还有很多图表&#xff0c;格式等等&#xff0c;想想就让人头疼欲裂。实践中摸索出一条相对靠…

挑战用React封装100个组件【010】

Hello&#xff0c;大家好&#xff0c;今天我挑战的组件是这样的&#xff01; 今天这个组件是一个打卡成功&#xff0c;或者获得徽章后的组件。点击按钮后&#xff0c;会弹出礼花。项目中的勋章是我通过AI生成的&#xff0c;还是很厉害的哈&#xff01;稍微抠图直接使用。最后面…

企业实践|广州新华学院携手泰迪智能科技开展大数据开发企业实践圆满结束

12月3日&#xff0c;新华学院健康学院携手广东泰迪智能科技股份有限公司联合开展大数据开发企业实践活动圆满结束&#xff0c;健康学院专业老师陈键聪及来自信息资源管理专业2023级24名学生参与此次活动结业仪式。泰迪智能科技董事长张良均、校企合作经理吴桂锋、钟秋平出席。 …

设计模式的艺术读书笔记

设计模式的艺术 面向对象设计原则概述单一职责原则开闭原则里氏代换原则依赖倒转原则接口隔离原则合成复用原则迪米特法则 创建的艺术创建型模式单例模式饿汉式单例与懒汉式单例的讨论通过静态内部类实现的更好办法 简单工厂模式 面向对象设计原则概述 单一职责原则 单一职责…