暴力解法 --- 当前版本SQL不支持开窗COUNT DISTINCT

店铺901国庆期间的7日动销率和滞销率

http://www.nowcoder.com/practice/e7837f66e8fb4b45b694d24ea61f0dc9

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

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)

全部评论
为什么用不了distinct 啊?是mysql版本问题吗?我一想就是滑动窗口问题
1 回复 分享
发布于 2022-03-15 23:44
感觉是个很丰富的心路历程
点赞 回复 分享
发布于 2021-12-05 23:03
这是看了你的答案后写的,能帮我看下我10-2号的数据哪里错了吗,自测运行都是对的,提交结果2号 的数据就不对 with t1 as (select '2021-10-01' dt,count(distinct a.product_id) ct from tb_order_detail a join tb_order_overall b on a.order_id=b.order_id join tb_product_info c on a.product_id=c.product_id where date(b.event_time) between date_sub('2021-10-01',interval 6 day) and '2021-10-01' and c.shop_id='901' union select '2021-10-02' dt,count(distinct a.product_id) ct from tb_order_detail a join tb_order_overall b on a.order_id=b.order_id join tb_product_info c on a.product_id=c.product_id where date(b.event_time) between date_sub('2021-10-02',interval 6 day) and '2021-10-02' and c.shop_id='901' union select '2021-10-03' dt,count(distinct a.product_id) ct from tb_order_detail a join tb_order_overall b on a.order_id=b.order_id join tb_product_info c on a.product_id=c.product_id where date(b.event_time) between date_sub('2021-10-03',interval 6 day) and '2021-10-03' and c.shop_id='901' ) select dt,round(ct/(select count(distinct product_id) from tb_product_info where shop_id='901'),3),round(1-ct/(select count(distinct product_id) from tb_product_info where shop_id='901'),3) from t1 order by dt;
点赞 回复 分享
发布于 2021-12-08 10:48
跟我想的一样哈哈哈,我也回去看了下那道题目觉得是滑动窗口
点赞 回复 分享
发布于 2022-02-17 23:26
我也是想用count(distinct) 结果不行
点赞 回复 分享
发布于 2022-03-11 19:08
我一开始也是想滑动窗口,最后也只能暴力解法。。。。。
点赞 回复 分享
发布于 2022-04-08 15:42
我也好痛苦 居然用不了。count(distinct od.product_id) over(order by date(event_time) rows 6 preceding),时间限制在最早不超过25号,本来是想这样做的
点赞 回复 分享
发布于 2023-01-04 16:51 广东

相关推荐

01-02 21:17
已编辑
西安理工大学 后端
程序员小白条:项目不太重要,你的优势的算法竞赛,然后多背相关的八股文,项目可以不作为重点考虑,面试可能就简单带过项目就行了,你可以直接写简历,背项目相关的八股文就行,也不用自己做,时间紧张的情况下,性价比最高
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务