HiveSQL一天一个小技巧:如何将分组内数据填充完整?

news2024/10/2 10:41:38

0 需求

1 需求分析

需求分析:需求中需要求出分组中按成绩排名取倒数第二的值作为新字段,且分组内没有倒数第二条的时候取当前值。

如果本题只是求分组内排序后倒数第二,则很简单,使用row_number()函数即可求出,但是本题问题点在于没有倒数第二时候需要保留当前值,如何优雅求出呢?

使用row_number()函数得到如下结果

with data as
         (select 111 as stu_id, 'class1' as class_name, 69 as score
          union all
          select 113 as stu_id, 'class1' as class_name, 74 as score
          union all
          select 112 as stu_id, 'class1' as class_name, 80 as score
          union all
          select 115 as stu_id, 'class1' as class_name, 93 as score
          union all
          select 114 as stu_id, 'class1' as class_name, 94 as score
          union all
          select 124 as stu_id, 'class2' as class_name, 70 as score
          union all
          select 121 as stu_id, 'class2' as class_name, 74 as score
          union all
          select 123 as stu_id, 'class2' as class_name, 78 as score
          union all
          select 122 as stu_id, 'class2' as class_name, 86 as score
          union all
          select 9999 as stu_id, 'class3' as class_name, 99 as score
         )
select stu_id
           , class_name
           , score
           , row_number() over (partition by class_name order by score desc ) rn1
          
      from data

根据上述结果,如何取出倒数第二值?上层使用case when rn = 2 then score end ,看看效果

with data as
         (select 111 as stu_id, 'class1' as class_name, 69 as score
          union all
          select 113 as stu_id, 'class1' as class_name, 74 as score
          union all
          select 112 as stu_id, 'class1' as class_name, 80 as score
          union all
          select 115 as stu_id, 'class1' as class_name, 93 as score
          union all
          select 114 as stu_id, 'class1' as class_name, 94 as score
          union all
          select 124 as stu_id, 'class2' as class_name, 70 as score
          union all
          select 121 as stu_id, 'class2' as class_name, 74 as score
          union all
          select 123 as stu_id, 'class2' as class_name, 78 as score
          union all
          select 122 as stu_id, 'class2' as class_name, 86 as score
          union all
          select 9999 as stu_id, 'class3' as class_name, 99 as score
         )
select stu_id
     , class_name
     , score
     , case when  rn1 = 2 then score end as  res
from (
         select stu_id
              , class_name
              , score
              , row_number() over (partition by class_name order by score desc ) rn1
              --, row_number() over (partition by class_name order by score  ) rn2
         from data
     ) t

倒数第二值是取出来了,但是还不符合要求,需求中要求该分组内生成的字段每一行全部为该值,如何做呢?这里有个小技巧,也是数据清洗的手段,如何将分组内空值用该分组内有值的值填充完整?我们采用max()函数开窗的技巧:max() over(partition by 分组字段),这样同一个组内的所有空值都会被赋值为同一个字段。SQL如下:


with data as
         (select 111 as stu_id, 'class1' as class_name, 69 as score
          union all
          select 113 as stu_id, 'class1' as class_name, 74 as score
          union all
          select 112 as stu_id, 'class1' as class_name, 80 as score
          union all
          select 115 as stu_id, 'class1' as class_name, 93 as score
          union all
          select 114 as stu_id, 'class1' as class_name, 94 as score
          union all
          select 124 as stu_id, 'class2' as class_name, 70 as score
          union all
          select 121 as stu_id, 'class2' as class_name, 74 as score
          union all
          select 123 as stu_id, 'class2' as class_name, 78 as score
          union all
          select 122 as stu_id, 'class2' as class_name, 86 as score
          union all
          select 9999 as stu_id, 'class3' as class_name, 99 as score
         )
select stu_id
     , class_name
     , score
     , max(case when  rn1 = 2 then score end ) over(partition by class_name)   as  res
from (
         select stu_id
              , class_name
              , score
              , row_number() over (partition by class_name order by score desc ) rn1
              --, row_number() over (partition by class_name order by score  ) rn2
         from data
     ) t

我们看到其结果值越来越符合预期,但是对于分组内只有一个值的如何处理呢?这里我们需要辅助判断,我们可以采用采用min() =max()判断,也可以采用percent_rank()=0判断等等,这里我们采用min() =max()判断,只要最大值等于最小值说明就分组内值唯一,最终SQL如下:

with data as
         (select 111 as stu_id, 'class1' as class_name, 69 as score
          union all
          select 113 as stu_id, 'class1' as class_name, 74 as score
          union all
          select 112 as stu_id, 'class1' as class_name, 80 as score
          union all
          select 115 as stu_id, 'class1' as class_name, 93 as score
          union all
          select 114 as stu_id, 'class1' as class_name, 94 as score
          union all
          select 124 as stu_id, 'class2' as class_name, 70 as score
          union all
          select 121 as stu_id, 'class2' as class_name, 74 as score
          union all
          select 123 as stu_id, 'class2' as class_name, 78 as score
          union all
          select 122 as stu_id, 'class2' as class_name, 86 as score
          union all
          select 9999 as stu_id, 'class3' as class_name, 99 as score
         )
select stu_id
     , class_name
     , score
     , max(case
               when rn1 != rn2 and rn1 = 2  --正序和倒序值不等 则取倒数第二的值 (rn1=2的值)
                   then score
               when rn1 = rn2 then score   --正序和倒序值相等 则取当前值
           end) over (partition by class_name) res
from (
         select stu_id
              , class_name
              , score
              , dense_rank()  over (partition by class_name order by score desc ) rn1
              , dense_rank() over (partition by class_name order by score) rn2 --用来辅助判断
             -- , percent_rank() over (partition by class_name order by score) pr --也可以采用该函数辅助判断(pr=0时候)
         from data
     ) t

2 小结

本文通过实际需求中的案例,讲解了如何将分组内空值补充完整的技巧,通过开窗,min()/max() over(partition by 分组字段)来补充,注意点max()函数中根据实际情况写case when语句,或构造符合实际需求的条件,往往数据清晰中会用到这一技巧

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

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

相关文章

Netty之io.netty.util.concurrent.Promise与io.netty.util.concurrent.Future初解

目录 目标 Netty版本 Netty官方API 三者之间的关系 基本使用方法 java.util.concurrent.Future io.netty.util.concurrent.Future io.netty.util.concurrent.Promise 目标 了解io.netty.util.concurrent.Promise与io.netty.util.concurrent.Future的基本使用方法。了解…

操作系统权限提升(二十四)之Linux提权-明文ROOT密码提权

系列文章 操作系统权限提升(十八)之Linux提权-内核提权 操作系统权限提升(十九)之Linux提权-SUID提权 操作系统权限提升(二十)之Linux提权-计划任务提权 操作系统权限提升(二十一)之Linux提权-环境变量劫持提权 操作系统权限提升(二十二)之Linux提权-SUDO滥用提权 操作系统权限…

Netty学习(二):线程模型

目录 一、线程模型基本介绍 二、传统阻塞IO服务模型 2.1 工作原理图 2.2 模型特点 2.3 问题分析 三、Reactor模式 3.1 完善传统阻塞I/O服务模型 3.2 Reactor模型原理图 3.3 Reactor模式中核心组成 3.4 Reactor模式分类 四、单 Reactor 单线程 4.1 原理图 4.2 方案说…

(二十一)操作系统-信号量机制2

文章目录一、知识总览二、知识点回顾三、信号量机制实现进程互斥四、信号量机制实现进程同步五、信号量机制实现前驱关系六、总结一、知识总览 二、知识点回顾 整型信号量:用一个整数型的变量作为信号量,用来表示系统中某种资源的数量。   记录型信号量…

4.5 正则表达式过滤查询数据

文章目录1. 概述2. 基本字符匹配3.LIKE关键字与正则表达式的区别4.进行OR匹配5.匹配几个字符之一6.匹配范围7.匹配特殊字符8.匹配多个实例9.定位符1. 概述 正则表达式用来匹配更加复杂的查询条件,例如你想从文件中提取电话号码,想从查找名字中间有数字的…

带你掌握webSocket 和 socket.io的基本用法

两者的作用和区别 作用:使得前后端可以随时地相互沟通。什么是互相沟通呢?像网络请求这种就是客户端向服务端的单向的沟通,当然,网络请求也可以实现双向的沟通,比如ajax 轮询,就是浏览器开个定时器不断的发…

Python虚拟环境(pipenv、venv、conda一网打尽)[通俗易懂]

一、什么是虚拟环境 1. 什么是Python环境 要搞清楚什么是虚拟环境,首先要清楚Python的环境指的是什么。当我们在执行python test.py时,思考如下问题: python哪里来?这个主要归功于配置的系统环境变量PATH,当我们在命…

山地车和公路车怎么选

公路车: 只能适应平坦的路面,骑行阻力小,速度快比较适合新手 山地车: 能适应所有路面,更注重操控性和舒适性 怎么选? 1、先决定用途 旅游:旅行车、山地车、 通勤:公路车 2、预…

如何使用BeaconEye监控CobaltStrike的Beacon

关于BeaconEye BeaconEye是一款针对CobaltStrike的安全工具,该工具可以扫描正在运行的主动CobaltStrike Beacon。当BeaconEye扫描到了正在运行Beacon的进程之后,BeaconEye将会监控每一个进程以查看C2活动。 工作机制 BeaconEye将会扫描活动进程或Mini…

G公司对接伍尔特wurth EDI项目案例

项目背景 对伍尔特wurth 而言,与其供应商开展成功的数字化项目通常是以自动连接开始的。通过这种方式,标准化的信息可以在彼此之间进行简单而自动的交换。这个流程被称为电子数据交换(EDI)。 EDI使得诸如订单、送货单、发票、订单…

Jmeter常用断言之JSON断言简介

JSON断言可以对服务器返回的JSON文档进行验证。 JSON断言有两种使用模式: 1.根据JSONPath能否在JSON文档中找到路径; 2.根据JSONPath提取值并对值进行验证。 结果判定:若文档格式为非JSON则断言失败;找不到路径断言失败&#xff1…

深度学习 | BN层原理浅谈

深度学习 | BN层原理浅谈 文章目录深度学习 | BN层原理浅谈一. 背景二. BN层作用三. 计算原理四. 注意事项为什么BN层一般用在线性层和卷积层的后面,而不是放在激活函数后为什么BN能抑制过拟合(有争议)一. 背景 神经网络在训练时,由于内存限制&#xff0…

Swagger2实现配置Header请求头

效果 实现 大家使用swagger肯定知道在代码中会写一个 SwaggerConfig 配置类,如果没有这个类swagger指定也用不起来,所以在swagger中配置请求头也是在这个 SwaggerConfig 中操作。 1、要实现配置请求头在配置swagger的Docket的bean实例中添加一个 globa…

用Python做了一个法律查询小工具,非常好用

用Python做了一个法律查询小工具,非常好用效果展示准备工作不会的话可以点我直达代码和视频讲解,我都准备好了主要代码哈喽兄弟,今天给大家分享一个Python tkinter制作法律查询小工具。 光爬虫大家也只能自己用用,就算打包了exe&…

安全狗受聘成为福州网信办网络安全技术支撑单位

近日,福州市委网信办召开了2022年度网络安全技术支撑单位总结表彰大会。 作为国内云原生安全领导厂商,安全狗也出席了此次活动。 据悉,会议主要对2022年度优秀支撑单位进行表彰,并为2023年度支撑单位举行授牌仪式。 本次遴选工…

2.1 黑群晖驱动:10代u核显硬解驱动(解决掉IP、重启无法连接问题)

本文提供了两种10代核显驱动方式:1)第一种(本文:二、仅修改i915.ko驱动10代u核显方法)为网上流传最多但是对主板兼容性要求很高,网上评论常会出现操作后无法识别IP(掉IP)的问题。因此,采用第一种…

vue-cli升级vue-cli5(webpack5引入)

一. 升级目标 vue-cli从v4版本升级到v5版本(同时升级到webpack5) node-sass不再支持,需要删除依赖,并将/deep/ 替换为v::deep方式 二. vue-cli4升级为vue-cli5 1.全局安装vue-cli npm install -g vue/cli// 检查是否更新成功 …

教你安装 Altium Designer23详细图文教程

Altium Designer (AD) 最新安装教程 ,ltium designer 显著地提高了用户体验和效率,利用时尚界面使设计流程流线化,同时实现了前所未有的性能优化。使用64位体系结构和多线程的结合实现了在PCB设计中更大的稳定性、更快的速度和更强的功能。Altium Designer 使您能够创建互联…

【项目精选】进销存管理系统的设计与实现(视频+源码+论文)

点击下载源码 1.1研究背景和意义 目前,许多的中小企业普遍存在一个问题:企业的决策者看到的进销存资料及相关报表都是比较繁杂,让本应该一目了然的结果因信息的分散使得产生的结果无法保持一致和完整,造成企业在进销存管理上问题很…

【C++】哈希

哈希一、unordered系列关联式容器二、哈希原理2.1 哈希映射2.2 哈希冲突2.2.1 闭散列—开放地址法2.2.2 代码实现2.2.3 开散列—拉链法2.2.4 代码实现三、哈希封装unordered_map/unordered_set3.1 基本框架3.2 迭代器实现3.2.3 operator*和operator->和operator!3.2.4 opera…