【Hive SQL 每日一题】统计最近1天/7天/30天商品的销量

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: 这段内容是关于SQL查询的示例,目标是统计`sales`表中最近1天、7天和30天的商品销量和销售次数。表结构包含`id`、`product_id`、`quantity`和`sale_date`字段。初始查询方法通过三个独立的子查询完成,但效率较低。优化后的查询使用了`lateral view explode`将数据炸裂,通过一次查询同时获取所有所需时间段的数据,提高了效率。示例中展示了优化前后的SQL代码及结果对比。

@[toc]

测试数据

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

INSERT INTO sales (id, product_id, quantity, sale_date) VALUES
(1, 101, 2, '2024-05-16'),
(2, 102, 1, '2024-05-15'),
(3, 101, 3, '2024-05-15'),
(4, 103, 4, '2024-05-14'),
(5, 102, 2, '2024-05-14'),
(6, 101, 1, '2024-05-13'),
(7, 103, 3, '2024-05-13'),
(8, 104, 5, '2024-05-12'),
(9, 102, 4, '2024-05-11'),
(10, 105, 2, '2024-05-11'),
(11, 104, 2, '2024-05-11'),
(12, 106, 2, '2024-05-10'),
(13, 102, 2, '2024-05-10'),
(14, 101, 2, '2024-05-08'),
(15, 101, 2, '2024-05-08'),
(16, 105, 2, '2024-05-05'),
(17, 104, 2, '2024-05-01'),
(18, 106, 2, '2024-04-29'),
(19, 102, 2, '2024-04-20'),
(20, 101, 2, '2024-04-15');

需求说明

统计最近 1 天/ 7 天/ 30 天各个商品的销量(假设今天为 2024-05-17)。

结果示例:

product_id recent_days total_quantity total_sales
101 1 3 3
101 7 6 4
101 30 10 6
... ... ... ...

结果按 recent_days 升序、total_quantity 降序排列。

其中:

  • product_id 表示商品 ID;
  • recent_days 表示最近 n 天;
  • total_quantity 表示该商品的销售数量;
  • total_sales 表示该商品的销售次数(用户一次性购买多件该商品,只记录一次销售)。

需求实现

-- 最近1天
select
  product_id,
  1 recent_days,
  sum(quantity) total_quantity, 
  count(product_id) total_sales 
from
  sales
where
  sale_date = "2024-05-16"
group by
  product_id
union all
-- 最近7天
select
  product_id,
  7 recent_days,
  sum(quantity) total_quantity, 
  count(product_id) total_sales 
from
  sales
where
  sale_date >= date_sub("2024-05-16",6) and sale_date <= "2024-05-16"
group by
  product_id
union all
-- 最近30天
select
  product_id,
  30 recent_days,
  sum(quantity) total_quantity, 
  count(product_id) total_sales 
from
  sales
where
  sale_date >= date_sub("2024-05-16",29) and sale_date <= "2024-05-16"
group by
  product_id
order by
  recent_days,total_quantity desc;

输出结果如下:

image.png

虽然这种方法可以算出结果,但是效率很低,我们需要算三次然后再进行合并,数据量一大的时候那就太慢了,那么有没有更好的方法呢?当然有!

首先来看优化完成后的 SQL 代码:

select
  product_id,
  rds recent_days,
  sum(quantity) total_quantity, 
  count(product_id) total_sales 
from
  sales lateral view explode(array(1,7,30)) tmp as rds
where
  sale_date >= date_sub("2024-05-16",rds - 1) and sale_date <= "2024-05-16"
group by
  rds,product_id
order by
  recent_days,total_quantity desc;

这里采用炸裂的方式,将一行数据变为了三行数据,(场景假设)如下所示:

炸裂前

id product_id quantity sale_date
1 101 2 2024-05-16
2 102 1 2024-05-15

炸裂后

id product_id quantity sale_date rds
1 101 2 2024-05-16 1
1 101 2 2024-05-16 7
1 101 2 2024-05-16 30
2 102 1 2024-05-15 1
2 102 1 2024-05-15 7
2 102 1 2024-05-15 30

炸裂后,会新增一列 rds,也就是用来表示最近 n 天的标记。其中每行数据都会变成 3 行数据,即使数据量变多了也没有关系,因为我们设置了 where 条件进行过滤,它只会保留符合要求的数据,同样也不会对我们的结果造成影响。

这里不理解的话,可能是不了解 lateral view explode 方法的使用规则,可以百度了解一下。

假设今日为:2024-05-17

例如:

  • 商品 1012024-05-16 有用户进行了购买,所以该数据会保留在最近 1 天/ 7 天/ 30 天商品的销量结果中。

  • 商品 1022024-05-15 有用户进行了购买,所以该数据会保留在最近 7 天/ 30 天商品的销量结果中。

  • ...

通过这种方法,我们不再需要写三个子查询然后再进行合并,一个查询即可搞定,提高了整体的运行速度。

image.png

在这么小数据量的场景下都节省了 1 秒左右,可见一斑。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
开启慢SQL设置long_query_time=0.1为啥会统计的sql却存在小于100毫秒的sql
32 1
|
2月前
|
SQL 分布式计算 Hadoop
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
75 3
|
2月前
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
47 0
|
2月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
52 0
|
2月前
|
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
96 0
|
4月前
|
SQL 存储 分布式计算
插入Hive表数据SQL
【8月更文挑战第10天】
|
4月前
|
SQL 物联网 数据处理
"颠覆传统,Hive SQL与Flink激情碰撞!解锁流批一体数据处理新纪元,让数据决策力瞬间爆表,你准备好了吗?"
【8月更文挑战第9天】数据时代,实时性和准确性至关重要。传统上,批处理与流处理各司其职,但Apache Flink打破了这一界限,尤其Flink与Hive SQL的结合,开创了流批一体的数据处理新时代。这不仅简化了数据处理流程,还极大提升了效率和灵活性。例如,通过Flink SQL,可以轻松实现流数据与批数据的融合分析,无需在两者间切换。这种融合不仅降低了技术门槛,还为企业提供了更强大的数据支持,无论是在金融、电商还是物联网领域,都将发挥巨大作用。
64 6
|
4月前
|
SQL 存储 关系型数据库
SQL SERVER 查询所有表 统计每张表的大小
SQL SERVER 查询所有表 统计每张表的大小
47 0
|
5月前
|
SQL 分布式计算 关系型数据库
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
Hadoop-12-Hive 基本介绍 下载安装配置 MariaDB安装 3台云服务Hadoop集群 架构图 对比SQL HQL
73 2