【类型】:经典题时间段
【场景】:已知日期和天数,得到某时间段(某个日期7天内的时间段)的某些指标
【分类】:时间函数、多表连接
分析思路
难点:
1.如何处理“只要当天任一店铺有任何商品的销量就输出该天的结果,即使店铺901当天的动销率为0。”的条件
新学到:
不用窗口函数,而是利用条件来确定某时间段(某个日期7天内的日期):datediff(dt_3, dt_7) between 0 and 6
(1)统计2021-10-01到2021-10-03之间有销售记录的日期
题目要求:只要当天任一店铺有任何商品的销量就输出该天的结果,即使店铺901当天的动销率为0。所以要统计2021-10-01到2021-10-03之间有销售记录的日期,因为有销售记录的才输出。
(2)统计店铺901产品的购买记录
三表连接把购买记录输出
- [使用]:join using()
(3)计算店铺901在2021年国庆头3天的7日动销率和滞销率,结果保留3位小数,按日期升序排序
动销率 = 有销量的商品/已上架总商品数;滞销率 = 1- 动销率
-
[使用]:left join
-
[使用]:datediff(dt_3, dt_7) between 0 and 6
最终结果
select 查询结果 [创作者;等级;连续回答天数]
from 从哪张表中查询数据[多表]
group by 分组条件 [创作者;等级]
having 判断条件 [连续回答问题的天数大于等于3]
order by 对查询结果排序 [创作者升序];
求解代码
错误代码
偷懒想要使用union暴力连接,发现不满足题目中的条件"只要当天任一店铺有任何商品的销量就输出该天的结果,即使店铺901当天的动销率为0。"
因为union的使用前提就是知道哪一天输出哪一天不输出,但是这个使用union时不能确定,所以还是得使用多表连接。
#计算店铺901在2021年国庆头3天的7日动销率和滞销率,结果保留3位小数,按日期升序排序
with
temp1 as(
select
'2021-10-01' as dt,
round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as sale_rate, #有销量的商品
1-round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as unsale_rate
from tb_order_overall
left join tb_order_detail using(order_id)
left join tb_product_info using(product_id)
where date(event_time) between '20210925' and '20211001'
and shop_id = '901'
and status = 1
)
,temp2 as(
select
'2021-10-02' as dt,
round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as sale_rate, #有销量的商品
1-round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as unsale_rate
fmysqlrom tb_order_overall
left join tb_order_detail using(order_id)
left join tb_product_info using(product_id)
where date(event_time) between '20210926' and '20211002'
and shop_id = '901'
and status = 1
)
,temp3 as(
select
'2021-10-03' as dt,
round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as sale_rate, #有销量的商品
1-round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as unsale_rate
from tb_order_overall
left join tb_order_detail using(order_id)
left join tb_product_info using(product_id)
where date(event_time) between '20210927' and '20211003'
and shop_id = '901'
and status = 1
)
select *
from temp1
union
select *
from temp2
union
select *
from temp3
方法一
with子句
with
temp as(
#统计2021-10-01到2021-10-03之间有销售记录的日期
select distinct
date(event_time) as dt_3
from tb_order_overall
where date(event_time) between '20211001' and '20211003'
and status = 1
)
,temp1 as(
#统计店铺901产品的购买记录
select
date(event_time) as dt_7,
product_id
from tb_order_overall
join tb_order_detail using(order_id)
join tb_product_info using(product_id)
where shop_id = '901'
and status = 1
group by dt_7,product_id
)
#计算店铺901在2021年国庆头3天的7日动销率和滞销率,结果保留3位小数,按日期升序排序
#动销率 = 有销量的商品/已上架总商品数
select
dt_3,
round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as sale_rate, #有销量的商品
1-round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as unsale_rate
from temp
left join temp1 on datediff(dt_3, dt_7) between 0 and 6
group by dt_3
order by dt_3
方法二
多表连接
#计算店铺901在2021年国庆头3天的7日动销率和滞销率,结果保留3位小数,按日期升序排序
##动销率 = 有销量的商品/已上架总商品数
select
dt_3,
round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as sale_rate, #有销量的商品
1-round(count(distinct product_id)/(select count(product_id) from tb_product_info where shop_id = '901'),3) as unsale_rate
from(
#统计2021-10-01到2021-10-03之间有销售记录的日期
select distinct
date(event_time) as dt_3
from tb_order_overall
where date(event_time) between '20211001' and '20211003'
and status = 1
) temp
left join(
#统计店铺901产品的购买记录
select
date(event_time) as time,
product_id
from tb_order_overall
join tb_order_detail using(order_id)
join tb_product_info using(product_id)
where shop_id = '901'
and status = 1
group by time,product_id
) temp1 on datediff(dt_3, time) between 0 and 6
group by dt_3
order by dt_3