【Hive SQL 每日一题】统计最近7天内连续下单3日的用户量

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 创建了一个名为`sales`的测试表,包含`user_id`、`product_id`、`quantity`和`sale_date`字段,插入了多条销售数据。需求是找出最近7天内连续下单3天的用户数量。SQL查询通过分组和窗口函数`row_number()`检查日期连续性,最终计算满足条件的唯一用户数。示例结果显示有3名用户符合条件。

@[toc]

测试数据

drop table if exists sales;
create table if not exists sales(
user_id int,
product_id int,
quantity int,
sale_date string);

INSERT INTO sales (user_id, product_id, quantity, sale_date) VALUES
(1001, 100, 1, '2024-05-16'),
(1001, 101, 3, '2024-05-15'),
(1001, 102, 2, '2024-05-14'),
(1001, 101, 2, '2024-05-14'),
(1002, 101, 3, '2024-05-17'),
(1002, 101, 3, '2024-05-16'),
(1002, 101, 2, '2024-05-15'),
(1002, 100, 1, '2024-05-15'),
(1002, 102, 1, '2024-05-14'),
(1002, 101, 3, '2024-05-11'),
(1002, 101, 2, '2024-05-10'),
(1003, 101, 3, '2024-05-17'),
(1003, 101, 3, '2024-05-16'),
(1003, 101, 2, '2024-05-14'),
(1003, 102, 1, '2024-05-13'),
(1003, 101, 2, '2024-05-10'),
(1004, 101, 3, '2024-05-17'),
(1004, 101, 2, '2024-05-14'),
(1004, 101, 2, '2024-05-10'),
(1005, 101, 3, '2024-05-17'),
(1005, 101, 4, '2024-05-16'),
(1005, 100, 2, '2024-05-16'),
(1005, 101, 1, '2024-05-16'),
(1005, 101, 2, '2024-05-15'),
(1005, 101, 3, '2024-05-13'),
(1005, 101, 2, '2024-05-12'),
(1005, 101, 2, '2024-05-11');

字段说明

  • user_id:用户ID;
  • product_id:商品ID;
  • quantity:商品销售数量;
  • sale_date:商品销售日期。

需求说明

统计最近 7 天内连续下单 3 日的用户量(假设今天为 2024-05-18)。

结果示例:

order_3_user_count
3

其中:

  • order_3_user_count 表示最近 7 天内连续下单 3 日及以上的用户个数。

需求实现

select
    count(distinct user_id) order_3_user_count
from
    (select
        user_id
    from
        (select
            user_id,  
            date_sub(sale_date,row_number() over(partition by user_id order by sale_date)) start_date
        from
            (select
                user_id,
                sale_date
            from
                sales
            group by
                user_id,sale_date)t1 )t2
    group by
        user_id,start_date
    having
        count(user_id) >= 3)t3;

输出结果如下:

image.png

一共有 3 名用户在 7 天内连续下单了 3 日及以上。

那么现在来说说这个需求是如何实现的,通过如下 1005 用户的购买数据来进行演化说明:

user_id product_id quantity sale_date
1005 101 3 '2024-05-17'
1005 101 4 '2024-05-16'
1005 100 2 '2024-05-16'
1005 101 1 '2024-05-16'
1005 101 2 '2024-05-15'
1005 101 3 '2024-05-13'
1005 101 2 '2024-05-12'
1005 101 2 '2024-05-11'

在这个需求中,并不关心用户购买了多少商品,在意的是用户是否进行了下单,同天下单多次的用户也只算作一次。

select
    user_id,
    sale_date
from
    sales
group by
    user_id,sale_date;

按用户、下单时间进行聚合,每天仅保留一条数据,聚合后,数据变化如下:

user_id sale_date
1005 '2024-05-17'
1005 '2024-05-16'
1005 '2024-05-15'
1005 '2024-05-13'
1005 '2024-05-12'
1005 '2024-05-11'

那么现在就有一个问题,就是该如何判断日期是否连续呢?

其实很简单,我们可以通过开窗的方式,计算日期是否连续,我这里是通过打标记来实现的。

那么具体是如何实现呢?需要先了解 row_number 方法的使用,如下所示:

user_id sale_date row_number start_date
1005 '2024-05-17' 6 '2024-05-11'
1005 '2024-05-16' 5 '2024-05-11'
1005 '2024-05-15' 4 '2024-05-11'
1005 '2024-05-13' 3 '2024-05-10'
1005 '2024-05-12' 2 '2024-05-10'
1005 '2024-05-11' 1 '2024-05-10'

通过上面的规律可以发现,如果日期是连续的,那么当它们减去一串顺序的数字后,得到的结果是一致的,我们可以利用这一规则,判断日期是否连续。

select
    user_id,  
    date_sub(sale_date,row_number() over(partition by user_id order by sale_date)) start_date
from
    (select
        user_id,
        sale_date
    from
        sales
    group by
        user_id,sale_date)t1;

既然求出了日期是否连续,那么下面就是分组判断各个用户是否满足连续购买 3 日的条件。

select
    user_id
from
    (select
        user_id,  
        date_sub(sale_date,row_number() over(partition by user_id order by sale_date)) start_date
    from
        (select
            user_id,
            sale_date
        from
            sales
        group by
            user_id,sale_date)t1 )t2
group by
    user_id,start_date
having
    count(user_id) >= 3;

image.png

现在得到的结果并不是最终的结果,因为某个用户(1005)可能在 7 日内满足多次该条件,但是在这个需求中,每个用户只能算一次,所以还需要去重才能得到最终结果。

select
    count(distinct user_id) order_3_user_count
from
    (select
        user_id
    from
        (select
            user_id,  
            date_sub(sale_date,row_number() over(partition by user_id order by sale_date)) start_date
        from
            (select
                user_id,
                sale_date
            from
                sales
            group by
                user_id,sale_date)t1 )t2
    group by
        user_id,start_date
    having
        count(user_id) >= 3)t3;

image.png

解本题的关键在于如何判断日期是否连续,通过 row_number 开窗可以轻松实现这一需求。

相关文章
|
SQL 分布式计算 资源调度
Dataphin功能Tips系列(48)-如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
如何根据Hive SQL/Spark SQL的任务优先级指定YARN资源队列
514 4
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
308 1
|
SQL 分布式计算 Hadoop
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
429 3
|
SQL 物联网 数据处理
"颠覆传统,Hive SQL与Flink激情碰撞!解锁流批一体数据处理新纪元,让数据决策力瞬间爆表,你准备好了吗?"
【8月更文挑战第9天】数据时代,实时性和准确性至关重要。传统上,批处理与流处理各司其职,但Apache Flink打破了这一界限,尤其Flink与Hive SQL的结合,开创了流批一体的数据处理新时代。这不仅简化了数据处理流程,还极大提升了效率和灵活性。例如,通过Flink SQL,可以轻松实现流数据与批数据的融合分析,无需在两者间切换。这种融合不仅降低了技术门槛,还为企业提供了更强大的数据支持,无论是在金融、电商还是物联网领域,都将发挥巨大作用。
257 6
|
SQL 存储 分布式计算
插入Hive表数据SQL
【8月更文挑战第10天】
1147 4
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
348 0
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
475 0
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
475 0
|
SQL 存储 关系型数据库
SQL SERVER 查询所有表 统计每张表的大小
SQL SERVER 查询所有表 统计每张表的大小
524 0