第一眼看到这题,觉得这是一道滑动窗口统计,觉得总体思路基本遵循这题:
https://blog.nowcoder.net/n/ed1e159ff8c84b7b8ddf4fd5c7a47c45
然而。。。这题很。。。恶心
恶心在哪?
我们能看到的数据是题目,以及自行测试的数据,最早到09.30,并没有7天以前的数据。
当然,我们可以提交一次,提前看到最终测试的数据是不是也是到09.30就结束了,但我。。。就比较刚。。。
题目要求统计7天,那我觉得即使测试数据不全,也应该尝试挑战通用的解法。
理由是我感觉牛客的很多题存在测试数据和用例解释不严谨的情况,反而会让我们的思维变得局限,发力点都在尽力靠近给我们的标准答案,而不是真正基于需求和对数据的理解,去挑战通用的解决方案。
然后我就倔强地构造了09.25 - 10.03的数据。。。
后面的操作基本遵循上面那题的思路,
然后一番折腾之后发现这题要统计区间的 COUNT DISTINCT product_id, 然而这个版本的SQL不支持开窗COUNT DISTINCT。。。。
。。。。
以下是暴力解法,不要学我hhh
WITH
a AS(
#当前已经上架的产品数(release_time早于当前event_time的产品)
SELECT
DATE(event_time) dt,
COUNT(DISTINCT product_id) stock_cnt
FROM tb_order_overall
JOIN tb_product_info ON release_time < DATE(event_time)
WHERE shop_id = 901
AND
DATE(event_time) BETWEEN '2021-09-25' AND '2021-10-03'
GROUP BY 1
),
b AS (
#区间内,每天售出的商品数
SELECT
'2021-10-01' dt,
COUNT(DISTINCT d.product_id) sale_cnt
FROM tb_order_overall o
LEFT JOIN tb_order_detail d USING(order_id)
LEFT JOIN tb_product_info i USING(product_id)
WHERE shop_id = 901
AND DATE(event_time) BETWEEN '2021-09-25' AND '2021-10-01'
UNION
SELECT
'2021-10-02' dt,
COUNT(DISTINCT d.product_id) sale_cnt
FROM tb_order_overall o
LEFT JOIN tb_order_detail d USING(order_id)
LEFT JOIN tb_product_info i USING(product_id)
WHERE shop_id = 901
AND DATE(event_time) BETWEEN '2021-09-26' AND '2021-10-02'
UNION
SELECT
'2021-10-03' dt,
COUNT(DISTINCT d.product_id) sale_cnt
FROM tb_order_overall o
LEFT JOIN tb_order_detail d USING(order_id)
LEFT JOIN tb_product_info i USING(product_id)
WHERE shop_id = 901
AND DATE(event_time) BETWEEN '2021-09-27' AND '2021-10-03'
)
SELECT
a.dt,
ROUND(sale_cnt / stock_cnt, 3) sale_rate,
ROUND(1 - sale_cnt / stock_cnt, 3) unsale_rate
FROM a JOIN b USING(dt)