HiveSQL题——数据炸裂和数据合并

目录

一、数据炸裂

0 问题描述

1 数据准备

2 数据分析

3 小结

二、数据合并

0 问题描述

1 数据准备

2 数据分析

3 小结

一、数据炸裂

0 问题描述

    如何将字符串1-5,16,11-13,9" 扩展成 "1,2,3,4,5,16,11,12,13,9" 且顺序不变。

1 数据准备

with data as (select '1-5,16,11-13,9' as a)

2 数据分析

 步骤一:explode(split(a, ',')) 炸裂 + row_number()排序,一行变多行,且对每行的数据排序,保证有序性。

with data as (select '1-5,16,11-13,9' as a)
select
    a,
    row_number() over () as rn
from (
         select
             explode(split(a, ',')) as a
         from data
     )tmp1;

输出结果:

步骤二: lateral view explode(split(a, '-'))  、max(b) - min(b) as diff

(1)lateral view +explode 侧写和炸裂,一行变多行,并将源表中每行的输出结果与该行连接;

 (2)group by a, rn .......  select  min(b)   as start_index 得到每个分组的起始值

 (3)max(b) - min(b) 得到每个分组的步长

with data as (select '1-5,16,11-13,9' as a)
select
    a,
    rn,
    min(b)          as start_data,
    max(b) - min(b) as diff
from (
         select
             a,
             rn,
             b
         from (
                  select
                      a,
                      row_number() over () as rn
                  from (
                           select
                               explode(split(a, ',')) as a
                           from data
                       ) tmp1
              ) tmp2
                  lateral view explode(split(a, '-')) table1 as b
     ) tmp3
group by a, rn;

 输出结果是:

步骤三: 根据步长生成索引值,起始值加上索引值获取展开值

(1) lateral view posexplode(split(space(cast (diff as int)), '')) table1 as pos, item;
   侧写和炸裂,根据分组的步长 diff  生成对应的索引值pos

 (2)(start_data + pos) as  str,起始值加上索引值获取展开值

with data as (select '1-5,16,11-13,9' as a)
select
    a,
    rn,
    cast ((start_data + pos) as int) as str
from (
         select
             a,
             rn,
             start_index,
             diff,
             pos
         from (
                  select
                      a,
                      rn,
                      min(b) as start_data,
                      max(b) - min(b) as diff
                  from (
                           select
                               a,
                               rn,
                               b
                           from (
                                    select
                                        a,
                                        row_number() over () as rn
                                    from (
                                             select
                                                 explode(split(a, ',')) as a
                                             from data
                                         ) tmp1
                                ) tmp2
                                    lateral view explode(split(a, '-')) table1 as b
                       ) tmp3
                  group by a, rn
              ) tmp4
                  lateral view posexplode(split(space(cast(diff as int)), '')) table1 as pos, val) tmp5
  order by rn;

输出结果是: 

步骤四: 对a,rn, diff 字段分组,拼接str字符串得到最终结果值

with data as (select '1-5,16,11-13,9' as a)
select
    concat_ws(',', collect_set(cast(str as string))) as result
from (
         select
             a,
             rn,
             cast((start_index + pos) as int) as str
         from (
                  select
                      a,
                      rn,
                      start_index,
                      diff,
                      pos
                  from (
                           select
                               a,
                               rn,
                               min(b)  as start_index,
                               max(b) - min(b) as diff
                           from (
                                    select
                                        a,
                                        rn,
                                        b
                                    from (
                                             select
                                                 a,
                                                 row_number() over () as rn
                                             from (
                                                      select
                                                          explode(split(a, ',')) as a
                                                      from data
                                                  ) tmp1
                                         ) tmp2
                                             lateral view explode(split(a, '-')) table1 as b
                                ) tmp3
                           group by a, rn
                       ) tmp4
                           lateral view posexplode(split(space(cast(diff as int)), '')) table1 as pos, val
              ) tmp5
     ) tmp6
group by a,rn,diff;

最终的输出结果:1,2,3,4,5,16,11,12,13,9 

3 小结

数据炸裂的思路一般是:
    1.计算区间【a,b】的步长(差值)diff;
    2.利用split分割函数+ posexplode等 将一行变成 diff+1 行,生成对应的下角标pos(pos的取值为【0,diff】);
    3.【a,b】区间的起始值 (a + pos) 将数据平铺开;
    4.基于平铺开后的数据集进一步加工处理,例如:分组聚合等。

二、数据合并

0 问题描述

   面试题:基于A表的数据生成B表数据

1 数据准备

create table if not exists  tableA
(
    id        string comment '用户id',
    name   string comment '用户姓名'
) comment 'A表';

insert overwrite table tableA values
    ('1','aa'),
    ('2','aa'),
    ('3','aa'),
    ('4','d'),
    ('5','c'),
    ('6','aa'),
    ('7','aa'),
    ('8','e'),
    ('9','f'),
    ('10','g');


create table if not exists  tableC
(
    id     string comment '用户id',
    name   string comment '用户姓名'
) comment 'C表';

insert overwrite table tableC values
    ('3','aa|aa|aa'),
    ('4','d'),
    ('5','c'),
    ('7','aa|aa'),
    ('8','e'),
    ('9','f'),
    ('10','g');

2 数据分析

 步骤1:寻找满足条件的断点

select
    id,
    name,
    if(name != lag_name, 1, 0) as flag
from (
         select
             id,
             name,
             lag(name, 1, name) over (order by cast(id as int)) as lag_name
         from tableA
     ) tmp1;

输出结果为:

 步骤2:断点处标记为1,非断点处标记为0,并对断点标记值进行累加,构造分组标签

select
    id,
    name,
    --并对断点标记值进行累加,构造分组标签
    sum(flag) over (order by cast(id as int)) grp
from (
         select
             id,
             name,
             --断点处标记为1,非断点处标记为0
             if(name != lag_name, 1, 0) flag
         from (
                  select
                      id,
                      name,
                      lag(name, 1, name) over (order by cast(id as int)) as lag_name
                  from tableA
              ) tmp1
     ) tmp2;

输出结果为:

步骤3:按照分组标签进行数据合并,并取得分组中最大值作为id

select
    max_id,
-- collect_list 数据聚合并拼接concat_ws
    concat_ws('|', collect_list(name)) as name
from (
         select
             name,
             grp,
             max(id) over (partition by grp) max_id
         from (
                  select
                      id,
                      name,
                      sum(if(name != lag_name, 1, 0)) over (order by cast(id as int)) as grp
                  from (
                           select
                               id,
                               name,
                               lag(name, 1, name) over (order by cast(id as int)) as lag_name
                           from tableA
                       ) tmp1
              ) tmp2
     ) tmp3
group by max_id, grp;

输出结果为:

通过max_id, grp分组,对name进行 concat_ws('|', collect_list(name)) 聚合拼接,得出最终的结果

3 小结

 断点分组问题的算法总结
 步骤1:寻找满足条件的断点
 步骤2:断点处标记值为1,非断点处标记为0
 步骤3:对断点标记值进行累加 sum(xx)over(order by xx),构造分组标签
 步骤4:按照分组标签进行分组求解问题


 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot144基于mvc的高校办公室行政事务管理系统设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计,课程设计参考与学习用途。仅供学习参考, 不得用于商业或者非法用途,否则,一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

如何编写具有完备性的测试用例 ? 具体思路是什么 ? 全套解决方案打包呈现给你 。

设计测试用例应该算是测试人员最为主要的工作之一 ,好的测试用例往往具有覆盖性强 ,扩展性高以及复用性好等特点 。该如何设计出好的测试用例 ?是我们每一位测试人员需要重点思考的问题 ,下面是我对设计测试用例设计的思考 &#…

全国疫情实时监测系统(附源码)

目录 一.项目背景 1.有力支持疫情防控知识传播 2.迅速锁定“涉疫”人员流动轨迹 3.开展疫情发展态势预测与溯源 4.一图胜过千言万语!!! 二.研究过程(项目技术的利用) 1.总述 2.所用技术介绍 2.1Python 2.2Pyt…

从零开始学Linux之gcc命令

首先我们需要知道有两种编程语言 编译型语言:要求必须提前将所有源代码一次性转换成二进制指令,也就是生成一个可执行程序,例如C、C、go语言、汇编语言等,使用的转换工具称为编译器。 解释型语言:一边执行一边转换&a…

解析电子名片二维码生成:便捷、灵活、个性化

在当今信息爆炸的时代,名片已经成为商务社交不可或缺的工具之一。然而,随着技术的不断发展,传统的纸质名片已经逐渐被电子名片生成二维码所取代。电子名片二维码不仅具备了传统名片的基本信息展示功能,更融合了数字化优势&#xf…

记一次java项目本地正常执行,打完包之后执行发现没有对应的类或配置的问题

1、起因 线上有个spark的任务出了问题(该任务是通过sparkstreaming读取kafka中的数据,处理完之后推到es中),问题出在kafka中数据是有更新的,但是es中的对应索引中的数据却只更新到月初,因此我需要排查处理…

IDEA 取消参数名称提示、IDEA如何去掉变量类型提醒

一、IDEA 取消参数名称显示 取消显示形参名提示 例如这样的提示信息 二、解决方法 1、File—>Setting–>Editor—>Inlay Hints—>Java 去掉 Show Parameter hints for 前面的勾即可,然后Apply—>Ok 2、右键Disable Hints

爬虫学习笔记-Cookie登录古诗文网

1.导包请求 import requests 2.获取古诗文网登录接口 url https://so.gushiwen.cn/user/login.aspxfromhttp%3a%2f%2fso.gushiwen.cn%2fuser%2fcollect.aspx # 请求头 headers {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like …

自定义注解实现记录日志功能(注解支持SpEL表达式)

一、首先创建个接口类Log import java.lang.annotation.*;/*** description: 自定义操作日志记录注解* author xizc**/ Target({ ElementType.PARAMETER, ElementType.TYPE, ElementType.METHOD }) Retention(RetentionPolicy.RUNTIME) Inherited Documented public interface …

JUnit

前言:自动化就是selenium脚本来实现的,JUnit是java的单元测试工具,只不过我们在实现自动化的时候需要借助一下JUnit库里面提供的一些方法。 1、Test Test :表示方法是测试方法,执行当前这个类的时候,会自动…

Unity之做一个最简单的FPS游戏demo

目录 😋FPS游戏Demo 💤1.新建FPS模板项目 ⚒️2.装备枪 💣3.设置射击功能 📺4.制造一个子弹预制体 🎮5.发射子弹 说起来小编学Unity差不多一个月了,都是利用上班摸鱼时间学的(doge.jpg&…

java+springboot校园体育场地预约预订使用系统vue+ssm

研究内容和研究方法 1.研究内容 网站主要包括管理员和用户两个部分,用户可以登录与注册自己的基本信息、查询哪些场地可以使用、提前预约场地、取消预约的场地、使用完场地后进行缴费。管理员可以审批用户的注册信息、对用户信息进行增删改查、查询场地的使用情况、…

【C++干货基地】C++引用与指针的区别:深入理解两者特性及选择正确应用场景

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 哈喽各位铁汁们好啊,我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的…

秋招面试—JS篇

2024 JavaScript面试题 1.new 操作符的工作原理 ①.创建一个新的空对象 ②.将这个对象的原型设置为函数的 prototype 对象 ③.让函数的this指向该对象,为函数添加属性和方法 ④.最后返回这个对象 2.什么是DOM,什么是BOM? DOM:文档对象…

AI日报:谷歌的“双子时代”:将第二代人工智能嵌入其所做的一切

谷歌强大的大型多模式模式Gemini正在进军搜索、广告、云、Bard等领域。Bard的付费订阅即将到来吗? 文章目录 一览Bard订阅即将到来?一代人工智能进入谷歌广告YouTube正在崛起收入上升但股价下跌 一览 谷歌首席执行官、母公司Alphabet的桑达尔皮查伊表示&…

Kotlin 协程:用源码来理解 ‘viewModelScope‘

Kotlin 协程:用源码来理解 ‘viewModelScope’ Kotlin 协程是 Kotlin 语言的一大特色,它让异步编程变得更简单。在 Android 开发中,我们经常需要在后台线程执行耗时操作,例如网络请求或数据库查询,然后在主线程更新 UI…

VBoxManage 命令行使用

VBoxManage: 序号命令作用1VBoxManage list vms# 查看当前所有虚拟机2VBoxManage list runningvms # 查看当前正在运行的虚拟机3VBoxManage startvm 虚拟机名 --type gui # 启动虚拟机4VBoxManage startvm 虚拟机名 --type headless# 无前端图形界面方式启动虚拟机…

Elasticsearch:构建自定义分析器指南

在本博客中,我们将介绍不同的内置字符过滤器、分词器和分词过滤器,以及如何创建适合我们需求的自定义分析器。更多关于分析器的知识,请详细阅读文章: 开始使用 Elasticsearch (3) Elasticsearch: analyzer…

Debezium发布历史101

原文地址: https://debezium.io/blog/2021/01/07/debezium-1-4-final-released/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. Debezium 1.4.0.Final 发布 2021 年 1 月 7 日 作者: 克里…

C#中的WebApi响应Accept头,自动返回xml或者json

Global.asax.cs中的Application_Start方法添加 GlobalConfiguration.Configuration.Formatters.Clear(); GlobalConfiguration.Configuration.Formatters.Add(new XmlMediaTypeFormatter()); GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter())…