关注公众号:大数据技术派,回复: 资料,领取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. GraalVM最佳实践,使用Java开发CLI、Desktop(JavaFX)、Web(SpringBoot)项目,并使用native-image技术把Java代码静态编译为独立可执行文件(本机映像)

    原创文章,转载请注明出处! 源码地址: Gitee Gtihub 介绍 GraalVM最佳实践,使用Java开发CLI.Desktop(JavaFX).Web(SpringBoot)项目,并使用nat ...

  2. tabix 操作VCF文件

    tabix 可以对NGS分析中常见格式的文件建立索引,从而加快访问速度,不仅支持VCF文件,还支持BED, GFF,SAM等格式. 下载地址: 1 https://sourceforge.net/pr ...

  3. nginx_install

    [root@MiWiFi-R1CM-srv ~]# yum install -y gcc-c++ zlib zlib-devel openssl openssl-devel pcre-devel pc ...

  4. Mysql的delimiter

    告诉MySQL解释器,该段命令是否已经结束了,mysql是否可以执行了.默认情况下,delimiter是分号;.在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令. 有时 ...

  5. Linux—ps -ef 命令输出信息的具体含义(显示所有正在运行的命令程序)

    linux 中使用 ps -ef 输出参数的具体含义 功能:显示所有正在运行的命令程序 UID: 说明该程序被谁拥有PID:就是指该程序的 IDPPID: 就是指该程序父级程序的 IDC: 指的是 C ...

  6. shell 脚本的基本定义

    注意不能有控制,指令之间 [1]shell脚本的基础知识 (1)shell脚本的本质 编译型语言 解释型语言 shell脚本语言是解释型语言 shell脚本的本质 shell命令的有序集合 (2)sh ...

  7. UE4之Slate: App启动与最外层Runtime结构

    UE4版本:4.24.3源码编译: Windows10 + VS开发环境 Slate为一套自定义UI框架,其绘制直接依赖的是OpenGL.DirectX这样的硬件加速AIP;可以理解为一个单独的2D图 ...

  8. Redis | 第9章 Lua 脚本与排序《Redis设计与实现》

    目录 前言 1. Lua 脚本 1.1 Redis 创建并修改 Lua 环境的步骤 1.2 Lua 环境协作组件 1.3 EVAL 命令的实现 1.4 EVALSHA 命令的实现 1.5 脚本管理命令 ...

  9. PC端页面转换成手机端页面的分辨率问题的理解

    PC端页面转换成手机端页面的分辨率问题的理解 px vw rem 假如就以a4纸模式为设计图 ,在a3纸模式中设计,然后设计出来展示在不同的a4纸模式上 通常是 750px -> 100vw / ...

  10. 学习java的第二十一天

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