题目来源:小红书
目录
- 1 题目
- 2 建表语句
- 3 题解
1 题目
有营销活动记录表,记录了每个品牌每次营销活动的开始日期和营销活动的结束日期,现需要统计出每个品牌的总营销天数。
注意:
1:苹果第一行数据的营销结束日期比第二行数据的营销开始日期要晚,这部分有重叠的日期的要去重计算。
2:苹果第二行数据的营销结束日期和第三行的开始日期不连续,2019-09-07以及2019-09-08不统计到营销天数中。
样例数据
+--------+-------------+-------------+
| brand | start_date | end_date |
+--------+-------------+-------------+
| 华为 | 2018-08-04 | 2018-08-05 |
| 华为 | 2018-08-04 | 2020-12-25 |
| 小米 | 2018-08-15 | 2018-08-20 |
| 小米 | 2020-01-01 | 2020-01-05 |
| 苹果 | 2018-09-01 | 2018-09-05 |
| 苹果 | 2018-09-03 | 2018-09-06 |
| 苹果 | 2018-09-09 | 2018-09-15 |
+--------+-------------+-------------+
样例结果
+--------+-----------+
| brand | act_days |
+--------+-----------+
| 华为 | 875 |
| 小米 | 11 |
| 苹果 | 13 |
+--------+-----------+
2 建表语句
CREATE TABLE IF NOT EXISTS t_marketing_act (
brand STRING, --品牌
start_date STRING, -- 营销活动开始日期
end_date STRING -- 营销活动结束日期
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS ORC;
insert into t_marketing_act(brand, start_date, end_date) values
('华为','2018-08-04','2018-08-05'),
('华为','2018-08-04','2020-12-25'),
('小米','2018-08-15','2018-08-20'),
('小米','2020-01-01','2020-01-05'),
('苹果','2018-09-01','2018-09-05'),
('苹果','2018-09-03','2018-09-06'),
('苹果','2018-09-09','2018-09-15');
3 题解
本题难点在解决交叉问题,但是题目给出的是开始日期和结束日期,我们根据开始和结束日期,使用生成函数,生成活动期间每天的记录,然后根据品牌分组,对日期进行去重即可。
-- 2. 根据品牌分组,act_date进行去重统计
with t as (
-- 1. 生成每次活动每天的记录
select
brand,
start_date,
end_date,
t.pos,
t.value,
date_add(start_date, t.pos) as act_date
from t_marketing_act
lateral view posexplode(split(space(datediff(end_date, start_date)), '')) t as pos, value)
select
brand,
count(distinct act_date) as act_days
from t
group by brand;
拓展:
- DATE_ADD函数在SQL和HiveQL(HQL)中的用法有所不同。
- SQL中的DATE_ADD:
- DATE_ADD(date, INTERVAL value unit)
- date:要操作的日期。
- value:要添加的时间间隔数值。
- unit:时间间隔的单位,例如DAY、MONTH、YEAR等。
- HiveQL中的DATE_ADD,通常用来向日期添加指定的天数。
- DATE_ADD(date, days)
- date:要操作的日期
- days:要添加的天数,可以是正数(增加天数)或负数(减少天数)。
- space(n)函数生成一个包含n个空格的字符串。
- 在Python中,将字符串按空字符串
''
分割是不合法的,会引发错误。但在Hive中,这种操作是合法的,并且常用于将字符串的每个字符分割成单独的元素。- 在HiveQL中,POSEXPLODE 是一个特殊的表生成函数,它用于将数组或映射类型的数据展开成多行,并且同时生成每个元素的索引和值。
假设有一个包含数组数据的表example_table
SELECT
id,
pos,
value
FROM example_table
LATERAL VIEW POSEXPLODE(values) exploded_table AS pos, value;
查询结果将会是:
在这个例子中:
- POSEXPLODE(values):将values列中的数组展开。
- LATERAL VIEW:将POSEXPLODE的结果与原始表一起展平。
- pos:数组元素的索引。
- value:数组元素的值。