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

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
大数据开发治理平台 DataWorks,不限时长
简介: 这段内容是关于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 秒左右,可见一斑。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
21天前
|
SQL HIVE
【Hive SQL 每日一题】环比增长率、环比增长率、复合增长率
该文介绍了环比增长率、同比增长率和复合增长率的概念及计算公式,并提供了SQL代码示例来计算商品的月度增长率。环比增长率是相邻两期数据的增长率,同比增长率是与去年同期相比的增长率,复合增长率则是连续时间段内平均增长的速率。文章还包含了一组销售数据用于演示如何运用这些增长率进行计算。
|
21天前
|
SQL HIVE
【Hive SQL 每日一题】统计用户连续下单的日期区间
该SQL代码用于统计用户连续下单的日期区间。首先按`user_id`和`order_date`分组并去除重复,然后使用`row_number()`标记行号,并通过`date_sub`与行号计算潜在的连续日期。接着按用户ID和计算后的日期分组,排除连续订单数少于2的情况,最后提取连续下单的起始和结束日期。输出结果展示了用户连续下单的日期范围。
|
21天前
|
SQL HIVE
【Hive SQL】字符串操作函数你真的会用吗?
本文介绍了SQL中判断字符串是否包含子串的几种方法。`IN`函数判断元素是否完全等于给定元素组中的某项,而非包含关系。`INSTR`和`LOCATE`函数返回子串在字符串中首次出现的位置,用于检测是否存在子串。`SUBSTR`则用于提取字符串的子串。`LIKE`用于模糊匹配,常与通配符配合使用。注意`IN`并非用于判断子串包含。
|
22天前
|
SQL HIVE
【Hive SQL 每日一题】统计最近7天内连续下单3日的用户量
创建了一个名为`sales`的测试表,包含`user_id`、`product_id`、`quantity`和`sale_date`字段,插入了多条销售数据。需求是找出最近7天内连续下单3天的用户数量。SQL查询通过分组和窗口函数`row_number()`检查日期连续性,最终计算满足条件的唯一用户数。示例结果显示有3名用户符合条件。
|
1月前
|
SQL 分布式计算 Hadoop
Hive SQL 优化
Hive SQL 优化
63 1
|
SQL 分布式计算 负载均衡
Hive SQL优化思路
Hive的优化主要分为:配置优化、SQL语句优化、任务优化等方案。其中在开发过程中主要涉及到的可能是SQL优化这块。
568 0
|
SQL 分布式计算 HIVE
|
7天前
|
SQL DataWorks NoSQL
DataWorks产品使用合集之如何将SQL Server中的数据转存到MongoDB
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
1月前
|
SQL API 流计算
实时计算 Flink版产品使用合集之在Mac M1下的Docker环境中开启SQL Server代理的操作步骤是什么
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
156 1
|
24天前
|
SQL 存储 搜索推荐
SQL server增删改查(1)
SQL server增删改查(1)
106 0

热门文章

最新文章