SQL技术问询:如何返回近30天全量产品销量及指定品类畅销榜
解决过去30天产品销量统计的两个需求
你这个SQL框架已经搭得差不多啦,不过还差几个关键条件才能满足你的两个需求,我来帮你调整完善下:
需求1:返回过去30天内的所有产品(包含未售出的)
核心要确保所有产品都被保留,同时统计过去30天的销量(没卖出去的就显示0)。这里最关键的是时间过滤的位置——不能放在WHERE里,否则没销售记录的产品会被过滤掉,得把它写在LEFT JOIN的ON子句里。
修正后的SQL:
SELECT a.productID, a.product, ISNULL(SUM(b.quantity), 0) AS countquantity FROM products a LEFT JOIN savedDetails b ON a.productid = b.productid -- 过滤过去30天的销售记录,这里假设savedDetails有create_time字段记录销售时间 AND b.create_time >= DATEADD(day, -30, GETDATE()) LEFT JOIN Category d ON d.Categorysec = a.Categorysec -- 补全你的品类关联条件 GROUP BY a.productID, a.product ORDER BY countquantity DESC;
需求2:生成指定品类过去30天的畅销榜单(返回全部产品按销量排序)
这个需求需要先限定目标品类,同时保留该品类下的所有产品,哪怕没销量也要显示,然后按销量从高到低排。同样要注意时间过滤的位置,另外可以用行号来标记排名。
修正后的SQL:
SELECT ROW_NUMBER() OVER (ORDER BY ISNULL(SUM(b.quantity), 0) DESC) AS RowNumber, a.productID, a.product, ISNULL(SUM(b.quantity), 0) AS countquantity, d.CategoryName -- 可选:显示品类名称,方便确认品类 FROM products a LEFT JOIN savedDetails b ON a.productid = b.productid AND b.create_time >= DATEADD(day, -30, GETDATE()) LEFT JOIN Category d ON d.Categorysec = a.Categorysec -- 指定你要统计的品类,比如品类ID是'C001',替换成你的实际字段和值 WHERE d.Categorysec = 'C001' GROUP BY a.productID, a.product, d.CategoryName ORDER BY countquantity DESC;
几个重要的细节提醒:
- 时间过滤的坑:要是把
b.create_time >= ...放在WHERE里,那些没销售记录的产品(b的字段全是NULL)会因为NULL >= 日期不成立被过滤掉,所以一定要放在LEFT JOIN的ON子句中。 - 无销量产品的处理:用
ISNULL(SUM(b.quantity), 0)把NULL转换成0,这样排序的时候没销量的产品会自然排在最后,也更符合业务展示需求。 - 排名的可选调整:如果你希望销量相同的产品排名相同(比如两个产品都卖了10件,排名都是1),可以把
ROW_NUMBER()换成RANK()或者DENSE_RANK(),根据你的业务需求选就行。
内容的提问来源于stack exchange,提问作者jasonkkt
相关产品推荐
相关产品推荐

