0 需 求

稀疏字段累计求和问题

1 问题分析

根据图片中数据变换的形式,可以看出是根据字段term补齐数据中缺失的日期,term为连续日期的个数,当为12时,表明由2018-12-21到2019-01-02连续日期个数为12,当补齐日期后,根据日期顺序求amount的累计值,注意的是,当日期补齐后,补齐的日期值是空的。此类问题在业务中经常出现,特别在求累计值时,如果日期不是连续的,很容易漏掉部分日期累计值,造成数据不完整。这类问题的核心点就是数据日期非连续,需要补齐连续的日期,那么如何补齐连续日期呢?看过我SQLBOY1000题专栏的同学应该明白有类似的题目,这里给出链接。

SQL重叠交叉区间问题分析--HiveSQL面试题30_莫叫石榴姐的博客-CSDN博客

HiveSql一天一个小技巧:如何构造连续日期_hive生成连续的日期_莫叫石榴姐的博客-CSDN博客

步骤1:根据数据日期,补全需要的连续日期

对于补齐连续日期,我们给出模板及核心语句

lateral view posexplode(split(space(term), '(?!$)')) temp as pos,val

其中space()函数表示取空格,目的是为了扩展数据使用,取多少空格由里面参数决定,split()中的正则(?!$)表示不是以空格结尾的就匹配,因为split()函数会多切出一个空格,我们需要去掉。

利用posexplode()函数生成索引,根据数据中的起始日期(min(value_date))+增长步长的方式可以补齐所有的日期。注意这里面是按月增长的,我们使用add_months函数,即

add_months(value_date, pos)

整体生成连续日期语句如下:

with data as
(select 'AAAA' as contract,'2018-12-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-03-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-06-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-09-21' as value_date,9439.30 as amount,12 as termunion allselect 'BBBB' as contract,'2018-12-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-02-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-06-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-09-02' as value_date,9439.30 as amount,10 as term
)
select contract, add_months(value_date, pos) value_date,termfrom (select contract, min(value_date) value_date, max(amount)     amount, max(term)       termfrom datagroup by contract) t1 lateral view posexplode(split(space(term), '(?!$)')) temp as pos,val

步骤2:用补齐的连续日期作主表关联数据表,并计算累计值。

注意:这里一定要用生成连续日期做主表与关联数据表,这样才能做累计计算时候不重不漏,此时

sum() over(partition by order by )中sum的值一定是数据表右表中的值,partition by和order by的值是主表中的值。

在准确计算非连续日期累计值的核心点也在于此,生成补齐的日期维度表一定是主表,然后去关联数据表。

最终具体SQL如下:

with data as
(select 'AAAA' as contract,'2018-12-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-03-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-06-21' as value_date,9439.30 as amount,12 as termunion allselect 'AAAA' as contract,'2019-09-21' as value_date,9439.30 as amount,12 as termunion allselect 'BBBB' as contract,'2018-12-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-02-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-06-02' as value_date,9439.30 as amount,10 as termunion allselect 'BBBB' as contract,'2019-09-02' as value_date,9439.30 as amount,10 as term
)select  dim.contract,dim.value_date,cast(sum(d.amount) over(partition by dim.contract order by dim.value_date)  as decimal(18,2)) amount,dim.term
from(select contract, add_months(value_date, pos) value_date,termfrom (select contract, min(value_date) value_date, max(amount)     amount, max(term)       termfrom datagroup by contract) t1 lateral view posexplode(split(space(term), '(?!$)')) temp as pos,val) dim
left join
(select contract,value_date,amountfrom data
) d
on dim.contract = d.contract and dim.value_date = d.value_date

结果如下:

问题补充:如何将缺失日期及缺失值补充完整呢?

直接根据相邻日期缺失的时间间隔,利用posexplode()函数将缺失日期及数据展开补齐,具体SQL如下:

with data as(select 'AAAA' as contract, '2018-12-21' as value_date, 9439.30 as amount, 12 as termunion allselect 'AAAA' as contract, '2019-03-21' as value_date, 9439.30 as amount, 12 as termunion allselect 'AAAA' as contract, '2019-06-21' as value_date, 9439.30 as amount, 12 as termunion allselect 'AAAA' as contract, '2019-09-21' as value_date, 9439.30 as amount, 12 as termunion allselect 'BBBB' as contract, '2018-12-02' as value_date, 9439.30 as amount, 10 as termunion allselect 'BBBB' as contract, '2019-02-02' as value_date, 9439.30 as amount, 10 as termunion allselect 'BBBB' as contract, '2019-06-02' as value_date, 9439.30 as amount, 10 as termunion allselect 'BBBB' as contract, '2019-09-02' as value_date, 9439.30 as amount, 10 as term)
select contract,add_months(value_date, pos) value_date,amount
from (select contract,value_date,amount,term,lead(value_date, 1, value_date) over (partition by contract order by value_date) next_value_datefrom data) tmp lateral view  posexplode (split (space( cast(months_between(next_value_date, value_date) as int)), " (?!$)")
) tmp AS pos,val;

结果如下:

2 小结

本文给出了一种非连续日期准确求解累计值的通用方法。通过本文可以学习到:

(1)连续日期的构造方法

(2)非连续日期准确求解累计值的方法

注意此类问题又叫稀疏字段累计求和问题

HiveSQL一天一个小技巧:如何精准计算非连续日期累计值【闪电快车面试题】相关推荐

  1. HiveSQL一天一个小技巧:如何借助于str_to_map进行行转列

    目录 0 需求描述 1 需求分析 2 小 结 0 需求描述 有如下表格 partner label value 001 原始证件号 9111030275820228X7 001 统一社会信用代码 91 ...

  2. HiveSql一天一个小技巧:如何不使用union all 进行列转行

    目录 0 需求 1 数据准备 2 数据分析 3 小结 0 需求 如下: 1 数据准备 create table t1 as select '1' as id ,'mike' as name ,'22' ...

  3. HiveSql一天一个小技巧:如何在表的特定位置添加字段

    hive表在某个特定的位置添加一个字段,在操作上是先在表的最后添加一个字段然后再将该字段移动到那个特定的位置 第一步:先在最后一个位置增加字段 alter table table_name add c ...

  4. 面试|HiveSQL常用的一些小技巧

    SORT_ARRAY 函数声明如下. ARRAY sort_array(ARRAY<T>) 用途:对给定数组中的数据排序. 参数说明:ARRAY,ARRAY类型的数据.数组中的数据可为任意 ...

  5. EXCEL小技巧:如何统计非空单元格

    http://club.excelhome.net/thread-1187271-1-1.html 下面教大家如果用函数统计非空单元格的数量 首先我们来介绍几个统计函数: 1.COUNT(value1 ...

  6. 计算机二级判断题技巧一半对一半错,计算机二级小技巧

    还有一个星期左右的时间计算机二级考试就要来了,小编今天给大家整理了计算机二级小技巧,下面就一起来了解看看吧! 选择题 选择题为单选题,是客观性试题,每道题的分值为2分,试题覆盖面广,一般情况下考生不可 ...

  7. 求一个任意实数c的算术平方根g_初中数学实数相关知识点:这些小技巧,解题有大用...

    实数在初中数学阶段算是一个大的版块,其中包括了很多的知识点,其中有一些简单的,也有一些较难的知识点,而在利用这些知识点解题的时候有时可能要转个弯,才能解的更快,而一般来说,实数的相关题目都是单选和填空 ...

  8. SQL用了两年多,分享2个最常用的小技巧

    导读:SQL是所有数据从业者必须打牢的基本功之一,扎实的SQL查询和适当的调优技巧是检验SQL能力的两大重要准则.个人曾经专门花费过好多时间用于提升SQL能力,期间也刷了大量的SQL题目,在这期间也不 ...

  9. C语言寻找第k小元素,小技巧——查找第k小的元素

    今天分享一个小技巧,虽然是小技巧但是还是很有价值的,曾经是微软的面试题.题目是这样的,一个无序的数组让你找出第k小的元素,我当时看到这道题的时候也像很多人一样都是按普通的思维,先排序在去第K个,但是当 ...

最新文章

  1. 炎热夏天到底如何让自己更凉快? - 生活至上,美容至尚!
  2. Linux系统中软件的“四”种安装原理详解:源码包安装、RPM二进制安装、YUM在线安装、脚本安装包...
  3. 每日英语:Vender Assault Shines Ugly Light on China's Urban Enforcers
  4. 大话西游之Office应用实例系列! 13
  5. 【前端】网页布局基础
  6. JSF AJAX请求的会话超时处理
  7. 一键搞定数码照片印前特效-【用可牛影像】
  8. 启动白屏处理_App启动优化一顿操作猛如虎
  9. 如何解决Windows 10屏幕字体缩放模糊问题
  10. html span离div块有边距,html块 div span
  11. MT6580 Android8.1调试移植费恩格尔指纹驱动
  12. 图像相似度对比分析软件,图像相似度计算方法
  13. python下载网页歌曲
  14. php对接微博热搜,基于PHP爬虫的微博热搜实时监控平台
  15. css文字不换行显示、超出显示点点点等实用性小记
  16. db_recovery_file_dest恢复区的空间保留问题
  17. 【干货】数据集网站汇总!
  18. Oracle_1th_查询语句
  19. oracle rfs进程过多,oracle 11.2 DataGuard少了日志应用进程RFS
  20. Unity引擎制作仿《文明》游戏

热门文章

  1. 终于知道程序员为什么没女朋友了
  2. 谷雨后的“时间玫瑰”
  3. Python 探究类的继承的使用
  4. HTML--学习网教程
  5. 软银董事长孙正义:想尽可能久的持有阿里巴巴股份
  6. vSphere、vSAN与高速网
  7. rEfind主题应用失败
  8. python hack js_飘逸的python - hack输出流便于调试
  9. Android vivo手机接入极光推送闪退
  10. iCheck插件使用