一、知识点梳理与拓展
从这一道真题,我所收获到的核心是各种表关联的用法。以前我常用到的表关联是:表1 JOIN 表2 ON 字段1=字段2
表关联的另2种用法:
- 用法1——这种用法可以适用于没有可直接用的关联字段情况
SELECT 字段1,字段2
FROM 表1,表2 WHERE 筛选条件
- 用法2——调整关联条件
SELECT 字段1,字段2
FROM 表1JOIN 表2 ON 条件
这里的条件比较宽泛WHERE后面可以跟啥ON后面也可以跟啥。
二、题目理解与解题步骤
1、题目理解
请计算店铺901在2021年国庆头3天的7日动销率和滞销率,结果保留3位小数,按日期升序排序。
难点1:动销率=销售数/在架数;滞销率=1-动销率
- 由上可知,需要统计两个核心指标:每天的销售商品数以及在架商品数。
难点2:如何判断头3天的7日商品销售情况。
- 我的第一念头是使用滚动窗口函数,试了后有两个因素导致本题无法使用滚动窗口函数:因素a.窗口函数内无法直接使用DISTINCT,例如COUNT(DISTINCT product_id)OVER()代码运行出错。因素b.滚动窗口函数需要销售日期是连续的,因而也不行。所以这个思路就PASS掉了。
- 参考了其他人的解题方法学习到了可以直接使用JOIN+ON的条件来进行时间判断,在后面解题步骤详细讲解。
整个解题思路是:先求每天在架商品,再求每天的销售商品,之后把两张表关联起来,就能计算动销率啦(动销率=销售数/在架数),当然,难点是用“ON DATEDIFF(dt,ddt) BETWEEN 0 AND 6”这个条件去关联两张表得出7日内的数据。
2、解题步骤
1)求每天的在架商品数:先找出每天的在架商品详情,再求每天的在架商品数。- 因为没有商品下架时间,所以默认只要商品销售日期大于上架日期,即为在架商品。
- 通过event_time>=release_time这个条件用来判断每天的在架商品id
- SELECT 字段1,字段2... FROM 表1,表2。这种关联表的方法不需要使用关键字段进行关联,直接把两个表格里的每一条数据都进行遍历排列。
SELECT DATE(event_time) dt,CASE WHEN event_time>=release_time THEN product_id END onsale #通过event_time>=release_time判断商品是否在架 FROM tb_order_overall,tb_product_info WHERE shop_id='901' AND DATE(event_time) BETWEEN '2021-10-01' AND '2021-10-03'; #看901店铺10月1日-3日期间每天的在架商品详情
- 求10月1日到10月3日的每天的在架商品数(此处默认,9月在架的商品,10月也都在架,不存在下架行为)
SELECT DATE(event_time) dt,COUNT( DISTINCT CASE WHEN event_time>=release_time THEN product_id END) onsale_cnt FROM tb_order_overall,tb_product_info WHERE shop_id='901' AND DATE(event_time) BETWEEN '2021-10-01' AND '2021-10-03' GROUP BY dt;
2)10月1日——3日每天的销售商品数
- 先统计一张9月26-10月3日期间,每天销售的商品详情表
SELECT DATE(event_time)ddt,product_id FROM tb_order_overall LEFT JOIN tb_order_detail USING(order_id) LEFT JOIN tb_product_info USING(product_id) WHERE shop_id='901' #901店铺每天的商品销售情况 AND DATE(event_time) BETWEEN '2021-09-26' AND'2021-10-03' #限制日期是为了缩小运行数据的范围,增加运行效率 ;
- 使用DATEDIFF(dt,ddt) BETWEEN 0 AND 6来关联每日在架商品数目表和每日销售表
SELECT dt,ddt,product_id,onsale_cnt FROM( SELECT DATE(event_time) dt,COUNT( DISTINCT CASE WHEN event_time>=release_time THEN product_id END) onsale_cnt FROM tb_order_overall,tb_product_info WHERE shop_id='901' AND DATE(event_time) BETWEEN '2021-10-01' AND '2021-10-03' GROUP BY dt ) t1 LEFT JOIN ( SELECT DATE(event_time)ddt,product_id FROM tb_order_overall LEFT JOIN tb_order_detail USING(order_id) LEFT JOIN tb_product_info USING(product_id) WHERE shop_id='901' AND DATEDIFF('2021-10-03',DATE(event_time)) BETWEEN 0 AND 8 ) t2 ON DATEDIFF(dt,ddt) BETWEEN 0 AND 6得出10月1日至3日期间(7日内的销售商品详单)
- 计算每日销售商品数
SELECT dt,COUNT(DISTINCT product_id)sale_cnt,onsale_cnt FROM( SELECT DATE(event_time) dt,COUNT( DISTINCT CASE WHEN event_time>=release_time THEN product_id END) onsale_cnt FROM tb_order_overall,tb_product_info WHERE shop_id='901' AND DATE(event_time) BETWEEN '2021-10-01' AND '2021-10-03' GROUP BY dt ) t1 LEFT JOIN ( SELECT DATE(event_time)ddt,product_id FROM tb_order_overall LEFT JOIN tb_order_detail USING(order_id) LEFT JOIN tb_product_info USING(product_id) WHERE shop_id='901' AND DATEDIFF('2021-10-03',DATE(event_time)) BETWEEN 0 AND 8 ) t2 ON DATEDIFF(dt,ddt) BETWEEN 0 AND 6 GROUP BY dt;
SELECT dt,ROUND(COUNT(DISTINCT product_id)/onsale_cnt,3)sale_rate ,ROUND(1-COUNT(DISTINCT product_id)/onsale_cnt,3)unsale_rate FROM( SELECT DATE(event_time) dt,COUNT( DISTINCT CASE WHEN event_time>=release_time THEN product_id END) onsale_cnt FROM tb_product_info,tb_order_overall WHERE shop_id='901' AND DATE(event_time) BETWEEN '2021-10-01' AND '2021-10-03' GROUP BY dt ) t1 LEFT JOIN ( SELECT DATE(event_time)ddt,product_id FROM tb_order_overall LEFT JOIN tb_order_detail USING(order_id) LEFT JOIN tb_product_info USING(product_id) WHERE shop_id='901' AND DATEDIFF('2021-10-03',DATE(event_time)) BETWEEN 0 AND 8 ) t2 ON DATEDIFF(dt,ddt) BETWEEN 0 AND 6 GROUP BY dt ORDER BY dt;