第一眼看到这题,觉得这是一道滑动窗口统计,觉得总体思路基本遵循这题:

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)