写一个包含多个事件四则运算的留存SQL ——impala hive

在实现一个留存业务需求时,碰到了一个难题,我需要提供展示一个按照如下图格式的数据,
在这里插入图片描述
day 1 ~ day n的第一行是留存用户数量,第二行是一个由多个事件组合执行四则算术运算得到的复合数值,这里碰到的难点主要是第二行的计算,如果只想查看第二行的解决方法可以点击这里

由于数据传输速率受限,我不能使用先查询出所有数据然后在代码里处理数据的方法,因此我需要在sql查询中尽量完成所有聚合计算以减少查询返回的行数

留存模型采用的是经典模型(Classic retention)留存用户的数量都是在各天day n独立计算的

这里day 1~day n第一行计算新用户留存数量,第二行的小数计算留存的新用户中某个混合事件的表现,混合事件可以是由某一事件计算得到的值或者由多个事件进行四则运算得到的组合事件的值,第二行的值计算是这篇文章要讲的重点

例如求某个活动事件有两个入口entrance_aentrance_b,结束通关标识事件为event_over

假设事件名称event_name"activety_1",用户表为t_user,事件表为t_event
t_user表的数据是这样的
在这里插入图片描述
t_event表的数据是这样的
在这里插入图片描述

1

计算第一行, 也就是计算经典留存模型day 1~day n的留存用户量,可以用t_user和t_event的join和case when语句实现:

with temp_user as (
select distinct `uid`, to_date(`firstday`) as `firstday`
from `t_user` 
where firstday >= "2022-02-01" and firstday < "2022-02-04"	-- 02-01 ~ 02-03的新用户
),
temp_event as (
select distinct`uid`,to_date(`event_date`) as `event_date`
from `t_event` 
where event_name = "activity_1" 
and event_date >= "2022-02-01" 
and event_date < "2022-02-07"   -- 02-03往后推3天-->day 3是02-06
)
select  
`firstday`, 
Count(distinct a.uid) as `new_user`,
Count(distinct case when event_date = date_add(firstday, 1) then a.uid end) as `day 1`,
Count(distinct case when event_date = date_add(firstday, 2) then a.uid end) as `day 2`,
Count(distinct case when event_date = date_add(firstday, 3) then a.uid end) as `day 3`
from temp_user a left join temp_event b on a.uid = b.uid
group by firstday

用以上sql语句查询得到的结果:
在这里插入图片描述
格式跟开头的图中的表格保持了一致,数值稍微验证一下可知没有问题,求第一行的留存用户数相对较简单

2

计算第二行的值,我想计算事件activity_1在day 1 ~ day n的通关表现,具体来说就是要计算出day 1~day n各留存用户的(entrance_a + entrance_b)/event_over

现在假设事件表t_event_1的内容是这样的
在这里插入图片描述
用户表t_user同之前的不变
在这里插入图片描述
要计算出day 1~day n各留存用户的(entrance_a + entrance_b)/event_over的表现,结果展示格式类似下面这张图
在这里插入图片描述
除了要按day 1 ~ day n展示数据外还涉及到属性entrance_a, entrance_b等的聚合计算,使用分析函数(Analytics Function)并不能降低得到的行数,这里我采用了先把要统计的数据(entrance_a, entrance_b, event_over)先分别计算出来按firstdayevent_date分组成行,然后再利用case when和求和语句把算出来的结果聚合到对应的day n,写出来的sql如下

-- 查询新用户
with temp_user as (
select distinct `uid`, to_date(`firstday`) as `firstday`
from `t_user` 
where firstday >= "2022-02-01" and firstday < "2022-02-04"	-- 02-01 ~ 02-03的新用户
),
-- 按firstday和event_date分组统计各个要查询的值
temp_event_1 as (
select a.uid,to_date(a.firstday) `firstday`,to_date(b.event_date) `event_date`,count(case when b.entrance = "a" then 1 end) as entrance_a,count(case when b.entrance = "b" then 1 end) as entrance_b,count(case when b.event_status = "event_over" then 1 end) as event_over
from t_user a left join t_event_1 b on a.uid = b.uidand to_date(b.event_date) between date_add(a.firstday, 1) and date_add(a.firstday, 3)and (b.entrance in ("a", "b") OR b.event_status = "event_over")    -- 注意不同的列必须要用OR分开查!因为在同一张表里面的限定了event_over就会有一部分的entrance事件查不到!and b.event_date >= "2022-02-01"  and b.event_date < "2022-02-07" -- 02-03往后推3天 --> 02-06
group by firstday, event_date, a.uid
)
-- 行转列减少返回的数据行数
select  evt.firstday,count(distinct evt.uid) `new user`,(sum(case when date_add(evt.firstday, 1) = evt.event_date then evt.entrance_a else 0 end ) + sum(case when date_add(evt.firstday, 1) = evt.event_date then evt.entrance_b else 0 end )) / sum(case when date_add(evt.firstday, 1) = evt.event_date then evt.event_over else 0 end ) `day 1`,(sum(case when date_add(evt.firstday, 2) = evt.event_date then evt.entrance_a else 0 end ) + sum(case when date_add(evt.firstday, 2) = evt.event_date then evt.entrance_b else 0 end )) / sum(case when date_add(evt.firstday, 2) = evt.event_date then evt.event_over else 0 end ) `day 2`,(sum(case when date_add(evt.firstday, 3) = evt.event_date then evt.entrance_a else 0 end ) + sum(case when date_add(evt.firstday, 3) = evt.event_date then evt.entrance_b else 0 end )) / sum(case when date_add(evt.firstday, 3) = evt.event_date then evt.event_over else 0 end ) `day 3`
from temp_event_1 evt
group by firstday

查询的结果
在这里插入图片描述
这里出现的null如果你想在sql中把它们变成0也可以使用zeroifnull()函数将每一列计算结果包住

验证正确性
根据用户表t_user和事件表t_event_1对比查询结果的正确性:
用户表
在这里插入图片描述
先看firstday在02-01的用户,只有0和1两个,对应的day 1就是他们在02-02的(entrance_a+entrance_b)/event_over表现值:
在这里插入图片描述
再检查02-02的用户2和3在day 1, day 2, day3的表现数值,也就是他们分别再02-03, 02-04和02-05的表现数值:
在这里插入图片描述
根据验证结果查询是没有问题的

day 1 ~ day n第二行的解决sql相对来说比较复杂,但是我目前没有想到更好的sql,如果有更好的方法查出结果,欢迎评论告诉我,感谢~

以上的模拟数据,都可以在这个链接(https://demo.gethue.com/hue/home)找到,账号密码登录的时候都是demo,找到Hive下的数据库选择default子库
在这里插入图片描述
Editor选择Hive就可以查询了
在这里插入图片描述
你也可以选择自己创建新表和插入数据模拟,以下是我的建表和插入数据的sql:

-- 用户表创建和值插入
CREATE TABLE `t_user`(`uid` int, `firstday` timestamp)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' 
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION'hdfs://namenode:8020/user/hive/warehouse/t_user';INSERT INTO t_user (uid, firstday)
VALUES(0, '2022-02-01 00:01:00'),(1,  '2022-02-01 00:04:30'),(2, '2022-02-02 10:00:00'),(3,  '2022-02-02 14:30:00')
;
-- 事件表t_event创建和插入值
CREATE TABLE `t_event`(`uid` int,`event_name` STRING,`event_date` TIMESTAMP)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' 
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION'hdfs://namenode:8020/user/hive/warehouse/t_event';INSERT INTO t_event (uid, event_name, event_date)
VALUES(1, "activity_1",  '2022-02-01 00:01:00'),(1, "activity_1",  '2022-02-01 00:04:30'),(1, "activity_1",  '2022-02-02 10:00:00'),(1, "activity_1",  '2022-02-02 14:30:00'),(2, "activity_1",  '2022-02-02 00:04:30'),(2, "activity_1",  '2022-02-03 10:00:00'),(2, "activity_1",  '2022-02-04 14:30:00'),(3, "activity_1",  '2022-02-05 09:00:00'),(3, "activity_1",  '2022-02-05 12:30:00'),(0, "activity_1",  '2022-02-06 14:30:00')
;-- 用户表t_event_1创建和值插入
CREATE TABLE `t_event_1`(`uid` int,`entrance` string,`event_status` STRING,`event_name` STRING,`event_date` TIMESTAMP)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' 
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat' 
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION'hdfs://namenode:8020/user/hive/warehouse/t_event_1';INSERT INTO `t_event_1` (uid, entrance, event_status, event_name, event_date)
VALUES(1, "a", "event_over", "activity_1",  '2022-02-01 00:01:00'),(1, "b", "event_over", "activity_1",  '2022-02-01 00:04:30'),(1, "a", "event_failed", "activity_1",  '2022-02-02 10:00:00'),(1, "b", "event_failed", "activity_1",  '2022-02-02 14:30:00'),(1, "a", "event_over", "activity_1",  '2022-02-06 14:30:00'),(2, "a", "event_over", "activity_1",  '2022-02-02 14:30:00'),  (2, "a", "event_failed", "activity_1",  '2022-02-02 00:04:30'),(2, "b", "event_over", "activity_1",  '2022-02-03 10:00:00'),(2, "a", "event_over", "activity_1",  '2022-02-04 14:30:00'),(2, "b", "event_failed", "activity_1",  '2022-02-05 16:30:00'),(3, "a", "event_over", "activity_1",  '2022-02-05 09:00:00'),(3, "b", "event_over", "activity_1",  '2022-02-02 00:04:30'),(3, "b", "event_over", "activity_1",  '2022-02-05 12:30:00'),(0, "a", "event_over", "activity_1",  '2022-02-06 14:30:00'),(0, "a", "event_over", "activity_1",  '2022-02-02 14:30:00'),  (0, "b", "event_over", "activity_1",  '2022-02-02 00:04:30')
;

注意你登录的session只会保持一段时间,大概十几分钟或更多?,一般你可以通过re-create session来重新打开并继续执行sql查询,如果re-create没有效果就只能重新登录了
在这里插入图片描述

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

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

相关文章

V4L2用户空间和kernel层driver的交互过程

这篇文章详细分析了V4L2用户空间和kernel层driver的交互过程&#xff0c;目的只有一个&#xff1a;更清晰的理解V4L2视频驱动程序的系统结构&#xff0c;驱动编程方法&#xff0c;为以后开发视频驱动打好基础既然从用户层出发探究驱动层&#xff0c;这里先贴出应用层code&#…

【Pytorch神经网络理论篇】 04 Variable类型与自动微分模块剖析

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

php 对象赋值后改变成员变量影响赋值对象

话不多说看代码 <?php class obj {}$obj1new obj();//实例化对象 $obj2$obj1;//赋值新对象 $obj1->name"test";//改变老对象的成员变量属性 var_dump($obj1); var_dump($obj2); $obj2->name"name";//改变新对象的成员变量属性 var_dump($obj1); …

Android Camera 通过V4L2与kernel driver的完整交互过程

原文地址&#xff1a;Android Camera 通过V4L2与kernel driver的完整交互过程 作者&#xff1a;xinyuwuxian Android Camera 通过V4L2与kernel driver的完整交互过程之前在 Android Camera 的执行流程http://blog.chinaunix.net/uid-26765074-id-3499537.html这篇文章中已经详细…

【Pytorch神经网络理论篇】 05 Module类的使用方法+参数Parameters类+定义训练模型的步骤与方法

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

BZOJ 2822: [AHOI2012]树屋阶梯 [Catalan数 高精度]

2822: [AHOI2012]树屋阶梯 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 779 Solved: 453[Submit][Status][Discuss]Description 暑假期间&#xff0c;小龙报名了一个模拟野外生存作战训练班来锻炼体魄&#xff0c;训练的第一个晚上&#xff0c;教官就给他们出了个难题。由…

【Pytorch神经网络理论篇】 06 神经元+神经网络模型+全连接网络模型

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

面试题:N皇后问题,思路和python解题笔记

n皇后问题算法思路和python解法 问题描述 n皇后问题&#xff0c;在nn的棋盘上&#xff0c;解出n个皇后所有不能互相攻击的摆法&#xff0c; 皇后在数组中用“Q”表示&#xff0c;空地用“.”表示 返回的数据结构格式要求&#xff1a;[[“.Q…”,“…Q”,“Q…”,“…Q.”],[“…

【Pytorch神经网络理论篇】 07 激活函数+Sigmoid+tanh+ReLU+Swish+Mish+GELU

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络理论篇】 08 Softmax函数(处理分类问题)

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

Python套接字编程Socket Progaming——1

本篇文章是Network And Web Programing-Socket Programing分类中的第一篇文章&#xff0c;内容主要包含 Socket概念理解Socket programing介绍一个简单的TCP协议的server-client程序支持同时处理多个客户端简单server-client连接程序socket的常用选项使用 理解socket概念 一…

【Pytorch神经网络理论篇】 09 神经网络模块中的损失函数

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

【Pytorch神经网络理论篇】 10 优化器模块+退化学习率

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

HAProxy负载均衡原理及企业级实例部署haproxy集群

HAProxy是一种高效、可靠、免费的高可用及负载均衡解决方案&#xff0c;非常适合于高负载站点的七层数据请求。客户端通过HAProxy代理服务器获得站点页面&#xff0c;而代理服务器收到客户请求后根据负载均衡的规则将请求数据转发给后端真实服务器。 同一客户端访问服务器&…

【Pytorch神经网络实战案例】07 预测泰坦尼克号上生存的乘客

1 样本处理 1.1 载入样本代码---Titanic forecast.py&#xff08;第1部分&#xff09; import numpy as np import torch import torch.nn as nn import torch.nn.functional as F from scipy import stats import pandas as pd import matplotlib.pyplot as plt import os o…

基于sanic的服务使用celery完成动态修改定时任务

首先声明一下 考虑到celery目前和asyncio的不兼容性&#xff0c;协程任务需要转换为非异步的普通方法才能被当做task加入定时&#xff0c;并且celery和asyncio使用可能会带来预想不到的问题&#xff0c;在celery官方第二次承诺的6.0版本融合asyncio之前&#xff0c;需要慎重考虑…

Pyscript,使用Python编写前端脚本

介绍 Anaconda的CEO Peter Wang在前两个月的时候发布了Pyscript&#xff0c;实现了在HTML支持Python的使用&#xff0c;整个引用过程甚至不需要安装任何环境&#xff0c;只需要使用link和script标签即可引用实现Python在HTML中运行的功能&#xff0c;在HTML中也可以运行和使用…

如何把应用程序app编译进android系统

转载&#xff1a;http://ywxiao66.blog.163.com/blog/static/175482055201152710441106/------------------------------------------------------------------把常用的应用程序编译到img文件中&#xff0c;就成了系统的一部分&#xff0c;用户不必自己安装&#xff0c;当然也卸…

【Pytorch神经网络实战案例】08 识别黑白图中的服装图案(Fashion-MNIST)

1 Fashion-MNIST简介 FashionMNIST 是一个替代 MNIST 手写数字集 的图像数据集。 它是由 Zalando&#xff08;一家德国的时尚科技公司&#xff09;旗下的研究部门提供。其涵盖了来自 10 种类别的共 7 万个不同商品的正面图片。 FashionMNIST 的大小、格式和训练集/测试集划分与…

PHP list的赋值

List右边的赋值对象是一个以数值为索引的数组&#xff0c;左边的变量的位置和赋值对象的键值一一对应&#xff0c;有些位置的变量可以省略不写。非末尾的被赋值变量省略时&#xff0c;分隔的逗号不能省略。左边变量被赋值的顺序是从右到左的。 1 list($a, ,$b,$c[],$c[]) [1,2…