题解 | 分析每个商品在不同时间段的销售情况

分析每个商品在不同时间段的销售情况

https://www.nowcoder.com/practice/eec7a93e1ab24233bd244e04e910d2f9

--版本1
with
    new_order_info as (
        select
            *
        from
            order_info
        where
            year(order_date) = 2024
            and month(order_date) in (4, 5, 6)
    ),
    temp as (
        select
            product_id,
            product_name,
            category,
            order_id,
            order_date,
            total_amount,
            supplier_id,
            supplier_name
        from
            product_info
            left join new_order_info using (product_id)
            join supplier_info using (product_id)
    ),
    temp2 as (
        select
            product_id,
            product_name,
            category,
            if(sum(total_amount) is null, 0, sum(total_amount)) as q2_2024_sales_total,
            supplier_name
        from
            temp
        group by
            product_id,
            product_name,
            category,
            supplier_name
    )
select
    product_id,
    product_name,
    q2_2024_sales_total,
    rank() over (
        partition by
            category
        order by
            q2_2024_sales_total desc
    ) as category_rank,
    supplier_name
from
    temp2
order by product_id asc


--版本2
WITH q2_2024_orders AS (
    SELECT product_id, SUM(total_amount) AS q2_2024_sales_total
    FROM order_info
    WHERE order_date >= '2024-04-01' AND order_date < '2024-07-01'
    GROUP BY product_id
)

SELECT 
    p.product_id,
    p.product_name,
    COALESCE(o.q2_2024_sales_total, 0) AS q2_2024_sales_total,
    RANK() OVER (PARTITION BY p.category ORDER BY COALESCE(o.q2_2024_sales_total, 0) DESC) AS category_rank,
    s.supplier_name
FROM 
    product_info p
LEFT JOIN q2_2024_orders o ON p.product_id = o.product_id
JOIN supplier_info s ON p.product_id = s.product_id
ORDER BY p.product_id ASC;

对比两个版本

1. ​不必要的中间步骤

  • 你创建了new_order_info临时表,只是简单筛选了日期,但后续又立即在temp中与其它表连接。这个中间步骤可以合并。
  • temptemp2两个临时表其实可以合并为一个步骤。

2. ​过于复杂的NULL值处理

  • if(sum(total_amount) is null, 0, sum(total_amount)) 这种写法有些冗余
  • 可以直接用COALESCE(SUM(total_amount), 0)更简洁

3. ​日期筛选方式不够高效

  • year(order_date) = 2024 and month(order_date) in (4, 5, 6)
  • 这种写法会导致索引失效(如果存在),直接使用日期范围更高效

4. ​连接操作可以更直接

  • 你在temp中先左连接product_info和new_order_info,然后又内连接supplier_info
  • 这种多步连接可以简化为一步完成

5. ​字段选择过于详细后又丢弃

  • temp中选择了许多字段(order_id, order_date等),但在temp2中又丢弃了它们
  • 应该只选择最终需要的字段

6. ​GROUP BY字段过多

  • temp2中GROUP BY了product_id, product_name, category, supplier_name
  • 实际上product_name和category通常由product_id决定,可能不需要全部列出

7. ​使用了USING而不是ON

  • USING语法虽然简洁,但在复杂查询中不如ON清晰明确

这些"啰嗦"的地方虽然不影响查询结果,但会影响:

  1. 查询的可读性
  2. 执行效率(特别是大数据量时)
  3. 维护的便利性

简化后的版本去掉了这些冗余,逻辑更直接,执行路径更清晰。

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-10 15:58
投个小米提前批试试水,先投一个岗位看看形势,不行就再沉淀一下投第二个岗位,莫辜负
Java抽象带篮子:我嘞个骚刚,已经开始研发6g了吗
投递小米集团等公司7个岗位
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
昨天 11:21
被夸真的超级开心,好可爱的姐姐
码农索隆:老色批们不用脑补了,我把金智妮的图找来了查看图片
点赞 评论 收藏
分享
06-20 17:42
东华大学 Java
凉风落木楚山秋:要是在2015,你这简历还可以月入十万,可惜现在是2025,已经跟不上版本了
我的简历长这样
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务