关注公众号:大数据技术派,回复: 资料,领取1024G资料。

时间滑动计算

今天遇到一个需求大致是这样的,我们有一个业务涉及到用户打卡,用户可以一天多次打卡,我们希望计算出7天内打卡8次以上,且打卡时间分布在4天以上的时间,当然这只是个例子,我们具体解释一下这个需求

  1. 用户一天可以打卡多次,所以要求打卡必须分布在4天以上;
  2. 7天不是一个自然周,而是某一天和接下来的6天,也就是说时间是是滑动的,窗口大小是7步长是1,说白了就是窗口计算;

其实说到这里你就想到了窗口函数,虽然这是一个窗口;但是hive却没有相应的窗口函数可以计算,接下来我们看一下怎么实现这个逻辑

外部调用实现时间循环

我们可以先写这样的一个SQL,就计算每个人在特定时间内是否满足我们的条件,我们先计算出每个人每天的打卡次数,例如这里我们的时间限制是'20210701' 到'20210707'

  select
b.union_id,to_date(ds,'yyyymmdd') as dt,count(1) as cnt
from
ods_la_daily_record_di b
where
-- 驱动表的时间限制
b.ds>='${bizdate}'
and b.ds<=${bizdate2}'
group by
b.union_id,ds

然后我们再判断这个时间端内,用户的打卡情况是否满足我们的条件

select
union_id,count(1) as 打卡天数, sum(cnt) as 打卡次数
from
(
select
b.union_id,ds,count(1) as cnt
from
ods_la_daily_record_di b
where
-- 驱动表的时间限制
b.ds>='${bizdate}'
and b.ds<='${bizdate2}'
group by
b.union_id,ds
)
group by
union_id
having
-- 时间分布在4天以上
count(1)>=4
-- 打卡次数在8次以上
and sum(cnt)>=8
;

这样我们就算出来我们需要的数据,接下来我们只需要用其他语言调用这个SQL ,传入不同的时间参数就可以了,利用编程语言实现时间的滑动,例如第一次传入'20210701-20210707' 第二次传入'20210702-20210708' 以此传入即可。

虽然可以实现,但是不好,因为我们还需要其他语言的调用,其实我们知道在SQL里面的关联其实就是通过循环实现的,那我们即然能通过循环实现这个需求,我们能不能通过关联实现这个需求呢

自关联实现滑动时间窗口

其实我们只要让用户某一天的数据和他接下来的6天的数据关联,然后按照这一天的数据进行汇总然后判断时候满足我们的条件即可,如果满足了条件,那么用户这一天的数据就是满足我们的需求的,也就是说这个用户是满足我们的需求的。

with tmp as(
-- 每个人每天打卡的次数
select
b.union_id,to_date(ds,'yyyymmdd') as dt,count(1) as cnt
from
ods_la_daily_record_di b
where
-- 驱动表的时间限制
b.ds>='${bizdate}'
group by
b.union_id,ds
)
select
union_id
from (
-- 满足条件的(用户-天)
select
a.union_id,a.dt,sum(b.cnt) as 打卡次数,count(1) as 打卡天数
from
tmp a
inner join
tmp b
on
a.union_id=b.union_id
and DATEDIFF(b.dt,a.dt)>=0
and DATEDIFF(b.dt,a.dt)<=6
group by
a.union_id,a.dt
having
-- 次数限制
sum(b.cnt)>=8
-- 天数限制
and count(1)>=4
)group by
-- 对用户去重
union_id
;

这里有一个问题需要注意一下,那就是我们满足条件sum(b.cnt)>=8 and count(1)>=4 的是用户某一天的数据,也就是说我们的维度是union_id-天,所以我们需要对这个数据按照用户为度进行去重。

扩展基于自然周的的滚动时间窗口计算

我们这里思考一个问题,那就是我们知道很多时候我们的计算其实是围绕着自然周的,虽然我们上面的计算不是自然周,那假设我们如果要求我们的计算是自然周呢,那这个时候我们应该怎么计算呢,其实我们数仓里有一种很表叫做时间维表,我们利用时间维表可以很方便的计算时间相关的东西,如果你没有的话建议去网上找一份,或者自己生成一份,因为使用起来很方便。

因为这个表的字段很多,这里我们截取了一部分放到这里了,下面我们看一下怎么使用时间维表进行计算。

select
UNION_ID,time_weeknum,count(1) as 打卡天数, sum(cnt) as 打卡次数
from(
select
b.union_id,ds,count(1) as cnt
from
ods_la_daily_record_di b
where
-- 驱动表的时间限制
b.ds>='${bizdate}'
and b.ds<='${bizdate2}'
group by
b.union_id,ds
) a
left join
dim_date_time b
on
a.ds=b.time_date
group by
-- 周的标识
UNION_ID,time_weeknum
HAVING
-- 时间分布在4天以上
count(1)>=4
-- 打卡次数在8次以上
and sum(cnt)>=8
;

这里我们就基于每个自然周算出了满足条件的人,当然我们还是要针对用户去重

总结

我们看到自关联其实可以达到滑动的效果,当然不仅仅体现在时间上,就像窗口除了时间窗口还是有基于个数的窗口,我们要在遇到类似问题的时候就可以选择这样的解决方案。

时间维表很重要,可以简化我们的计算,如果没有的话,需要创建一个。

交流群

加我微信:ddxygq,回复加群,我拉你进技术交流群。

猜你喜欢

数仓建模—指标体系

数仓建模—宽表的设计

Spark SQL知识点与实战

Hive计算最大连续登陆天数

Flink计算pv和uv的通用方法

Hive实战—时间滑动窗口计算的更多相关文章

  1. uva12174 滑动窗口+预处理

    注意理解题意,不是排列种类,而是下一个排序出现的时间滑动窗口,具体见代码,写了很多注释(紫书的思路1理解有点麻烦...)注:可以画一个轴来方便理解 #include<iostream> # ...

  2. Spark-Streaming之window滑动窗口应用

    Spark-Streaming之window滑动窗口应用,Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据,会被 ...

  3. 57、Spark Streaming: window滑动窗口以及热点搜索词滑动统计案例

    一.window滑动窗口 1.概述 Spark Streaming提供了滑动窗口操作的支持,从而让我们可以对一个滑动窗口内的数据执行计算操作.每次掉落在窗口内的RDD的数据, 会被聚合起来执行计算操作 ...

  4. Flink 滑动窗口使用触发器会触发多个窗口的计算

    之前有小伙伴在群里说:滑动窗口使用触发器让每条数据都触发一次计算 但是他并没有得到预期的结果:每条数据都触发一次计算,输出一条结果,而是每天数据都输出了很多条结果 为什么会这样呢? 写了个小案例,来解 ...

  5. 【图解】你还在为 TCP 重传、滑动窗口、流量控制、拥塞控制发愁吗?看完图解就不愁了

    每日一句英语学习,每天进步一点点: 前言 前一篇「硬不硬你说了算!近 40 张图解被问千百遍的 TCP 三次握手和四次挥手面试题」得到了很多读者的认可,在此特别感谢你们的认可,大家都暖暖的. 来了,今 ...

  6. tcp协议头窗口,滑动窗口,流控制,拥塞控制关系

    参考文章 TCP 的那些事儿(下) http://coolshell.cn/articles/11609.html tcp/ip详解--拥塞控制 & 慢启动 快恢复 拥塞避免 http://b ...

  7. TCP 滑动窗口和 拥塞窗口

    转http://coolshell.cn/articles/11609.html 滑动窗口 -- 表征发送端和接收端的接收能力 拥塞窗口-- 表征中间设备的传输能力 TCP滑动窗口 需要说明一下,如果 ...

  8. storm 1.0版本滑动窗口的实现及原理

    滑动窗口在监控和统计应用的场景比较广泛,比如每隔一段时间(10s)统计最近30s的请求量或者异常次数,根据请求或者异常次数采取相应措施.在storm1.0版本之前,没有提供关于滑动窗口的实现,需要开发 ...

  9. tcp滑动窗口详解(2)

    http://blog.csdn.net/yujun00/article/details/636495 ARQ与滑动窗口概念  滑动窗口协议,是TCP使用的一种流量控制方法.该协议允许发送方在停止并等 ...

随机推荐

  1. 联盛德 HLK-W806 (五): W801开发板上手报告

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  2. Pollard-Rho 算法

    Pollard-Rho 一种复杂度大概在 $ O(n^{\frac 1 4} \log n) $ 的分解质因数方法. Miller-Rabin 给定一个 $ 10^{18} $ 范围的数,判断质数 由 ...

  3. IOI 2020 国家集训队作业

    \(\checkmark\) 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf674G arc103_f \(\checkmark\) cf594E agc034_f agc0 ...

  4. Perl 语言入门6-9

    ---- 第6章 哈希----------- 简介 键值对.键和值都是任意标量,但键总是会被转换成字符串. 键唯一,值可重复. 应用场景:一组数据对应到另一组数据时. 如找出重复/唯一/交叉引用/查表 ...

  5. 60-Lowest Common Ancestor of a Binary Search Tree

    Lowest Common Ancestor of a Binary Search Tree My Submissions QuestionEditorial Solution Total Accep ...

  6. Python三元表达式,列表推导式,字典生成式

    目录 1. 三元表达式 2. 列表推导式 3. 字典生成式 3.1 字典生成式 3.2 zip()方法 1. 三元表达式 """ 条件成立时的返回值 if 条件 else ...

  7. 21-Add Two Numbers-Leetcode

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  8. hbase调优

    @ 目录 一.phoenix调优 1.建立索引超时,查询超时 2.预分区 hbase shell预分区 phoenix预分区 3.在创建表的时候指定salting. 4.二级索引 建立行键与列值的映射 ...

  9. 学习java的第二十三天

    一.今日收获 1.java完全学习手册第三章算法的3.2排序,比较了跟c语言排序上的不同 2.观看哔哩哔哩上的教学视频 二.今日问题 1.快速排序法的运行调试多次 2.哔哩哔哩教学视频的一些术语不太理 ...

  10. Java、Scala类型检查和类型转换

    目录 Java 1.类型检查 2.类型转换 Scala 1.类型检查 2.类型转换 Java 1.类型检查 使用:变量 instanceof 类型 示例 String name = "zha ...