HiveSQL刷题(查询首次下单后第二天连续下单的用户比率)

本文通过SQL查询,分析了订单信息表中首次下单后第二天继续下单的用户比例,并详细展示了如何处理用户重复下单及连续下单的数据逻辑。

Platform address:vue-sqleditor

题目需求:

从订单信息表(order_info)中查询首次下单后第二天仍然下单的用户占所有下单用户的比例,结果保留一位小数,使用百分数显示,
期望结果如下:
percentage
<string>
70.0% 

需要用到的表:

订单信息表:order_info
order_id (订单id)    user_id (用户id)    create_date (下单日期)    total_amount (订单金额)
1    101    2021-09-30    29000.00
10    103    2020-10-02    28000.00

建表语句:

create table order_info(

    order_id BIGINT,

    user_id BIGINT,

    create_date STRING,

    total_amount DOUBLE)

ROW FORMAT DELIMITED  

  FIELDS TERMINATED BY '\t'

STORED AS INPUTFORMAT  

  'org.apache.hadoop.mapred.TextInputFormat'  

OUTPUTFORMAT  

  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';

插入样例数据:

Insert into order_info 

Select 1,101,'2021-09-27',29000.00

Union all

Select 2,103,'2020-10-02',28000.00

Union all

Select 3,101,'2021-09-28',29000.00

Union all

Select 4,101,'2021-09-30',29000.00

Union all

Select 5,103,'2020-10-03',28000.00

Union all

Select 6,103,'2020-10-04',28000.00

Union all

Select 7,104,'2020-10-02',28000.00

Union all

Select 8,104,'2020-10-02',28000.00

Union all

Select 9,104,'2020-10-03',28000.00

Union all

Select 10,104,'2020-10-04',28000.00;

需求分析:

排除用户一天购买多次的情况

select user_id,create_date from order_info group by user_id,create_date

取出每个用户按天排序的序号

select user_id,create_date,row_number() over(partition by user_id order by create_date) as rnk from (select user_id,create_date from order_info  group by user_id,create_date)s1

取出每个用户下单日期与按天排序的序号之间的差值(若差值即首次下单日期的前一天的个数大于等于2,则说明此用户有首次下单后第二天仍然下单的情况)

select user_id,create_date,rnk,date_sub(create_date,rnk) as date_diff from (select user_id,create_date,row_number() over(partition by user_id order by create_date) as rnk from (select user_id,create_date from order_info  group by user_id,create_date)s1)s2

取出连续两天下单的用户

select user_id,date_diff,count(1) as cnt from (select user_id,create_date,rnk,date_sub(create_date,rnk) as date_diff from (select user_id,create_date,row_number() over(partition by user_id order by create_date) as rnk from (select user_id,create_date from order_info  group by user_id,create_date)s1)s2)s3 group by user_id,date_diff having cnt>=2

排除用户有多次连续两天下单的可能

select user_id from (select user_id,date_diff,count(1) as cnt from (select user_id,create_date,rnk,date_sub(create_date,rnk) as date_diff from (select user_id,create_date,row_number() over(partition by user_id order by create_date) as rnk from (select user_id,create_date from order_info  group by user_id,create_date)s1)s2)s3 group by user_id,date_diff having cnt>=2)s3 group by user_id

left join获取到首次下单后第二天仍然下单的用户占所有下单用户的比例

select concat(100*sum(if(s5.user_id is not null,1,0))/count(1),'%') as percentage from 

(select user_id from order_info group by user_id)s4 

left join 

(select user_id from (select user_id,date_diff,count(1) as cnt from (select user_id,create_date,rnk,date_sub(create_date,rnk) as date_diff from (select user_id,create_date,row_number() over(partition by user_id order by create_date) as rnk from (select user_id,create_date from order_info group by user_id,create_date)s1)s2)s3 group by user_id,date_diff having cnt>=2)s3 group by user_id)s5 

on s4.user_id=s5.user_id

最终SQL:

select
  concat(
    100 * sum(if(s5.user_id is not null, 1, 0)) / count(1),
    '%'
  ) as percentage
from
  (
    select
      user_id
    from
      order_info
    group by
      user_id
  ) s4
  left join (
    select
      user_id
    from
      (
        select
          user_id,
          date_diff,
          count(1) as cnt
        from
          (
            select
              user_id,
              create_date,
              rnk,
              date_sub(create_date, rnk) as date_diff
            from
              (
                select
                  user_id,
                  create_date,
                  row_number() over(
                    partition by user_id
                    order by
                      create_date
                  ) as rnk
                from
                  (
                    select
                      user_id,
                      create_date
                    from
                      order_info
                    group by
                      user_id,
                      create_date
                  ) s1
              ) s2
          ) s3
        group by
          user_id,
          date_diff
        having
          cnt >= 2
      ) s3
    group by
      user_id
  ) s5 on s4.user_id = s5.user_id

AC时间:

2022年12月08日22:56:25

### 使用 HiveSQL 计算留存率 为了计算留存率,在互联网行业通常关注的是用户在特定时间段内的行为模式。具体来说,如果希望了解新用户的留存情况,则可以通过比较不同时间窗口内活跃的用户数量来实现这一目标。 对于给定的时间周期(如日、周或月),可以定义首次登录日期作为起点,并跟踪这些用户在未来相同长度周期内的再次访问状况。通过这种方式能够评估应用程序保持用户参与度的效果[^2]。 #### 示例数据结构假设 假设有如下表 `user_log` 来记录每次用户的活动: | log_day | device_id | app_id | |---------------|---------------|--------| | YYYY-MM-DD | string | int | 这里 `log_day` 是用户登录的具体日期;`device_id` 和 `app_id` 组合起来唯一标识一位用户。 #### 留存率计算逻辑 要计算第 N 天的日留存率,即某天注册的新用户中有多少人在之后的第 N 天也进行了登录操作。这涉及到两个主要部分: 1. 找到每一天新增加的独立用户集合; 2. 对于每一个这样的新用户集合作为基线,查看他们在未来几天是否有重复出现。 基于上述思路,下面给出一段用于计算7日内留存率(HiveQL)SQL 查询语句示例: ```sql WITH new_users AS ( SELECT DISTINCT device_id, MIN(log_day) OVER(PARTITION BY device_id ORDER BY log_day ASC RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) first_login_date FROM user_log ), retained_users_7d AS( SELECT n.device_id FROM new_users n JOIN user_log l ON n.device_id = l.device_id AND datediff(l.log_day,n.first_login_date)=7 ) SELECT DATE_FORMAT(n.first_login_date,'yyyy-MM-dd') as reg_date, COUNT(DISTINCT n.device_id) as total_new_users, COUNT(DISTINCT r.device_id) as retained_users_count, ROUND(COUNT(DISTINCT r.device_id)*100/COUNT(DISTINCT n.device_id),2) as retention_rate_percent FROM new_users n LEFT OUTER JOIN retained_users_7d r USING(device_id) GROUP BY n.first_login_date; ``` 此查询首先创建了一个临时视图 `new_users` ,它包含了每个用户的最早一次登录时间和对应的设备ID。接着构建另一个名为 `retained_users_7d` 的子查询,用来找出那些恰好在初次登录后的第七天上又回来使用的用户群体。最后一步则是汇总统计并计算出相应的百分比形式表示的留存比率[^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值