一、问题:留存率计算(SQL)
字段及表说明:
表名:user_log
字段名:
log_day:登录日期
device_id:用户设备id
app_id:用户app的id,其中device_id和app_id确定唯一的用户

1.1计算某日留存率(次日、3日、7日、30日)

--计算次日、3日、7日、30日留存率
select a.log_day 首次登录日期,
count(user_id_d1)/count(user_id_d0) retention_d1,
count(user_id_d3)/count(user_id_d0) retention_d3,
count(user_id_d7)/count(user_id_d0) retention_d7,
count(user_id_d30)/count(user_id_d0) retention_d30 from(
--找出新增
select distinct log_day,device_id||app_id user_id_d0 from user_log a where log_day=log_day'day'
and device_id||app_id not in(select distinct device_id||app_id from user_log bwhere b.log_day<a.log_day)
)a
left join (select distinct log_day,device_id||app_id user_id_d1 from user_log where log_day=(log_day'day'+1) b on a.user_id_d0=b.user_id_d1
left join (select distinct log_day,device_id||app_id user_id_d3 from user_log where log_day=(log_day'day'+3) c on a.user_id_d0=c.user_id_d3
left join (select distinct log_day,device_id||app_id user_id_d7 from user_log where log_day=(log_day'day'+7) d on a.user_id_d0=d.user_id_d7
left join (select distinct log_day,device_id||app_id user_id_d30 from user_log where log_day=(log_day'day'+30) e on a.user_id_d0=e.user_id_d30
group by a.log_day

1.2计算每日留存率(次日、3日、7日、30日)

-- 创建留存率储存表
create table user_retention_monitior(
log_day date,retention_d1 number,retention_d3 number,
retention_d7 number,retention_d30 number
);-- 清空表
truncate table user_retention_monitior;
declare
day date;    --变量声明-- 程序主体
begin
select min(log_day) into day from user_log;   --变量赋初始值
loopinsert into user_retention_monitior-- 计算留存select a.log_day,count(b.user_id_d1)/count(a.user_id_d0) retention_d1,count(c.user_id_d3)/count(a.user_id_d0) retention_d3,count(d.user_id_d7)/count(a.user_id_d0) retention_d7,count(e.user_id_d30)/count(a.user_id_d0) retention_d30from(select distinct log_day,app_id||device_id user_id_d0 from user_log a where log_day=log_day'day' and app_id||device_id not in( select distinct pp_id||device_id from user_logwhere log_day<log_day'day' ))a left join(select distinct log_day,app_id||device_id user_id_d1 from user_log where log_day=(log_day'day'+1))b on a.user_id_d0=b.user_id_d1 left join(select distinct log_day,app_id||device_id user_id_d3 from user_log where log_day=(log_day'day'+3))c on a.user_id_d0=c.user_id_d3 left join(select distinct log_day,app_id||device_id user_id_d7 from user_log where log_day=(log_day'day'+7))d on a.user_id_d0=d.user_id_d7 left join(select distinct log_day,app_id||device_id user_id_d30 from user_log where log_day=(log_day'day'+30))e on a.user_id_d0=e.user_id_d30group by a.log_day;commit;day:=day+1;  --循环exit when day>=truc(sysdate);   --结束条件
end loop;
end;select * from user_retention_monitior;

二、问题:连续登陆问题(Hive语法)
基础数据准备:

1. 表结构
表名: user_login
字段名:
user_id string comment '用户id'
login_dt string comment '用户登陆时间'2. 数据格式
user_id login_dt
1       2020-05-01
1       2020-05-02
1       2020-05-043. 格式转换(login_dt由字符串格式转为时间格式)
to_date(from_unixtime(UNIX_TIMESTAMP(login_dt,'yyyy-MM-dd'))) as login_dt

连续登陆计算的两个思路:
①可先找出最近几天的日期,然后计算与当期日期的差值。
相应函数:lead/lag + datediff(或date_sub/date_add均可)

LAG(col,n,DEFAULT) 用于统计窗口内往上第n行值
第一个参数为列名,第二个参数为往上第n行(可选,默认为1),第三个参数为默认值(当往上第n行为NULL时候,取默认值,如不指定,则为NULL)LEAD(col,n,DEFAULT) 用于统计窗口内往下第n行值

②先对用户按登陆日期排序;根据登陆日期与排序差值进行分组统计。
相应函数:row_number() + date_sub

思路1:
比如求连续三天登陆,可以将当天上一条和下一条数据获取到,然后保证now-lag=lead-now=1即可:

//2. 要求now-lag=lead-now=1
select user_id from(
//1. 获取当天前后各一条数据
select user_id,login_dt,
lag(login_dt,1) over(partition by user_id order by login_dt) as lag_dt_01,
lead(login_dt,1) over(partition by user_id order by login_dt) as lead_dt_01
from user_login)temp1
where datediff(login_dt,lag_dt_01)=1 and datediff(lead_dt_01,login_dt)=1

如果连续多天,可以取更多数据,或者全用lag/lead函数。

思路2:

//2. 将用户根据登陆时间和序号的差值进行分组,得到连续登陆的起止日期、连续登陆的天数
select user_id,
min(login_dt) as start_dt,
max(login_dt) as end_dt,
count(1) as continue_dayfrom(
//1. 将用户按登陆时间排序号
select user_id,login_dt,
row_number() over(partition by user_id order by login_dt) as rn from user_login
)temp1
group by user_id,date_sub(login_dt,rn)

若需统计连续大于N天登陆的用户,可结合Having子句进行筛选。
参考链接: 连续登陆问题

三、TOP-N
基础数据准备:

每个顾客访客访问任何一个店铺的任何一个商品时都会产生一条访问日志.
访问日志存储的表名为Visit,访客的用户id为user_id,被访问的店铺名称为shop.
请统计每个店铺访问次数top3的访客信息.输出店铺名称、访客id、访问次数

思路及代码:

// 3. 取前三名
select shop,user_id,visit_num from(
// 2. 统计每个页面各用户的访问次数排序select shop,user_id,visit_num,row_num() over(partition by shop,user_id order by visit_num desc) as visit_sortfrom(// 1. 统计每个用户每个页面的访问次数select shop,user_id,count(1) as visit_num from visitgroup by shop,user_id)temp1
)temp2
where visit_sort<=3

四、行列互换
1. 将行中数据(数组),拆分为多行,On-to-many maping问题
基础数据准备:

-----------------------------------------------------
原式数据movie表:movie          category《疑犯追踪》      悬疑,动作,科幻,剧情
《Lie to me》      悬疑,警匪,动作,心理,剧情
《战狼 2》       战争,动作,灾难
-----------------------------------------------------
结果数据movie       category_name《疑犯追踪》         悬疑
《疑犯追踪》      动作
《疑犯追踪》      科幻
《疑犯追踪》      剧情
《Lie to me》     悬疑
《Lie to me》    警匪
《Lie to me》    动作
《Lie to me》    心理
《Lie to me》    剧情
《战狼 2》        战争
《战狼 2》        动作
《战狼 2》        灾难

思路及代码:UDTF函数(User-Defined Table-Generating Functions)与Lateral view结合使用

select movie,category_name from movie
lateral view explode(split(category),',') tmpTable as category_name

2. "多行"转"一行"问题
基础数据准备:

-----------------------------------------------------
原始数据constellation表:name  constellation   blood_type
孙悟空     白羊座             A
大海  射手座             A
宋宋  白羊座             B
猪八戒     白羊座             A
凤姐  射手座             A-----------------------------------------------------
结果数据
--把星座和血型一样的人归类到一起。结果如下:射手座,A     大海|凤姐
白羊座,A   孙悟空|猪八戒
白羊座,B   宋宋

思路及代码:使用group_concat函数

2. 根据新字段进行多行合并:group_concat()
select base,
group_concat(name separator '|') as namefrom(
1. 将星座和血型整合为新字段
select concat(constellation,‘,’,blood_type) as base,name from constellation
)temp1
group by base

若没有group_concat()函数,可以用concat_ws(separator,collect_set(column)) 代替。

五、学生选课情况
1. 类似进行透视功能,将列数据透视为矩阵数据
需求描述:

原始数据
----------------course表-----------------
id course
1   a
1   b
1   c
1   e
2   a
2   c
2   d
2   f
3   a
3   b
3   c
3   e预期结果:表中的1表示选修,表中的0表示未选修
----------------结果展示------------------id    a    b    c    d    e    f
1     1    1    1    0    1    0
2     1    0    1    1    0    1
3     1    1    1    0    1    0

思路及代码:

  1. 以数组形式整理每个学生选课信息;
  2. 判断数组数据是否在全量数组中。
    collect_set()、array_contains()以及case when实现。
3. 判断选课信息是否可匹配到
select id,
case when array_contains(id_course,course[0]) then 1 else 0 end as a,
case when array_contains(id_course,course[1]) then 1 else 0 end as b,
case when array_contains(id_course,course[2]) then 1 else 0 end as c,
case when array_contains(id_course,course[3]) then 1 else 0 end as d,
case when array_contains(id_course,course[4]) then 1 else 0 end as e,
case when array_contains(id_course,course[5]) then 1 else 0 end as ffrom(
4. 以数组形式整理每个学生的选课信息
select id,id_course,course from(
select id,collect_set(course) as id_course from course
group by id)as temp1 cross join(
select sort_array(collect_set(course)) as course from course
)as temp2)

关于collect_set() 和 array_contains()函数用法:

  1. collect_list():根据某个字段分组后,把分在一组的数据合并在一起,默认分隔符’,’ 。
  2. collect_set():在collect_list()的基础上去重 另:set聚合无序,可以使用sort_array()函数进行排序。
  3. array_sort():对数组内数据进行排序,sort_array(e: column, asc: boolean),默认升序排序。
  4. array_contains():类似于in的用法,array_contains(数组,值) 判断数组中是否有某值。
    参考:Hive面试题

数据运营-常见问题 留存率/连续登陆等(SQL Hive)相关推荐

  1. 数据运营-计算留存率和转化率(漏斗分析Python)

    一.案例数据 在数据运营中,留存率分析和转化率(漏斗)分析是经常用到的,本文结合具体案例总结了如何利用python求n日留存率以及各环节间转化率. 指标释义 案例数据集介绍: 本文是利用淘宝app的运 ...

  2. 数据分析行业中的数据运营是怎么一回事?

    现在由于物联网和大数据的蓬勃发展,使得数据分析行业异常火爆,现在市场上的数据分析行业的岗位是非常多的,比如说包括数据工程师.数据运维.数据分析师.数据运营.产品数据方向等,一般工程师都是搞开发的,都是 ...

  3. SQL计算QQ连续登陆天数

    最近遇到一个SQL查询需求:计算QQ连续登陆天数? 连续登陆天数不间断,如果有一天没登陆就重新计算. 数据准备 mysql> create table user_login(user_id in ...

  4. SQL——最大连续登录天数、当前连续登录天数、最大连续未登录天数问题、连续登陆N天用户、连续座位号

    问题: 最大连续登录天数 当前连续登录天数 最大连续未登录天数 连续登陆3天用户(三种方法) 选出连续座位的编号 前三个问题所用数据: 原数据表:user_active表 表字段:用户.新增日期.活跃 ...

  5. SQL求用户的最大连续登陆天数

    建表插入数据 create table tmp_continous (id STRING ,time DATETIME );INSERT OVERWRITE TABLE tmp_continous S ...

  6. SQL计算连续登陆天数大于等于3天的用户

    其中给出了用户(id)和用户登陆时间(dt)两列 其中要处理把登陆时间截取到日,然后根据id和登陆时间dt进行去重,然后得到如下的数据集 再进行下面的代码 select id, sdate, edat ...

  7. sql案例分析:统计连续登陆、日活、蚂蚁森林、排名等

    # 当天新用户hive -e \'select count(1) from hm2.daily_helper \where guid not in (select guid from hm2.hist ...

  8. mysql 连续七天不登录_【SQL】查询连续登陆7天以上的用户

    查询7天连续登陆用户这个问题很经典,解决方法也有很多,这里我讲一下笔者的方法,希望对大家有帮助. 具体思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row ...

  9. 超详细解析:使用SQL语句查询连续登陆7天的用户信息

    假设有如下表tb_user,现输出连续登陆7天的用户id 方法一思路: 1.因为每天用户登录次数可能不止一次,所以需要先将用户每天的登录日期去重. 2.再用row_number() over(part ...

最新文章

  1. PHP autoload 函数
  2. 关于input type=“text”文本框的 默认宽度
  3. c++ clr编译dll在c#调用时出现“试图加载不正确的格式”“找不到dll”错误的解决...
  4. android decorView详解
  5. 如何提高web应用的响应速度(性能)
  6. linux中gtk下定义label颜色,设置GtkLabel的背景颜色和字体颜色
  7. 《Python数据分析实战》day2: Pandas中取得某行或者是某列的一点思考
  8. 使用pienv安装python虚拟环境(学习记录)
  9. 实验三 Python表达式
  10. 深入理解机器学习(一)——二分类模型评价指标详解(上)
  11. C语言中printf格式输出
  12. Kubernetes 学习路径
  13. Viruses!!!!!
  14. python与seo实战课程it技术_python与SEO实战课程学习B计划
  15. Android Support Library介绍
  16. 生产者消费者3.0 阻塞队列版本
  17. iphone13支持双卡双待吗 苹果13是5g吗
  18. JavaWeb搭建简易个人博客
  19. python 给手机发送邮件消息
  20. kali linux改root密码

热门文章

  1. 低压差DC-DC 小体积5V转3.3V 2.5V 1.8V 大电流降压IC
  2. windows socket网络编程一:最简单的服务器和客户端搭建
  3. linux renice命令,Linux nice和renice命令教程(7个示例)
  4. PhysGAN: Generating Physical-World-Resilient Adversarial Examples for Autonomous Driving
  5. QGIS实现tiff文件转png、jpg等
  6. 游戏后端架构设计注意事项
  7. 初中级前端面试题—完整版
  8. 电脑错误代码0x8007007e怎么修复?
  9. mvn清理缓存_使用Maven清理项目
  10. 口袋电脑,到底是个什么东东?