如何用SQL按月份和日期统计各商品的最低平均价格?
解决方案:SQL统计商品最低日均价格及对应信息
明确需求:针对每个商品,计算其每日的平均销售价格,再找出该商品所有日均价格中的最低值,同时返回该最低价格对应的月份、日期及销售门店。
修正后的SQL语句
SELECT Grocery_Item, Month, Sales_Day, Sales_Date, Store_Name, Avg_Sales_Price FROM ( SELECT Grocery_Item, MONTH(Sales_Date) AS Month, Sales_Day, Sales_Date, Store_Name, ROUND(AVG(Sales_Price), 2) AS Avg_Sales_Price, ROW_NUMBER() OVER ( PARTITION BY Grocery_Item ORDER BY AVG(Sales_Price) ASC ) AS price_rank FROM Grocery_Data GROUP BY Grocery_Item, Sales_Date, Store_Name, Sales_Day ) ranked_data WHERE price_rank = 1;
关键修正点说明
- GROUP BY列修正:原查询GROUP BY未包含
Store_Name和Sales_Date,但SELECT引用了这些非聚合列,违反SQL标准导致报错。修正后将所有非聚合列纳入GROUP BY,确保分组逻辑合法。 - 窗口函数逻辑:通过
PARTITION BY Grocery_Item对每个商品单独分组排序,ORDER BY AVG(Sales_Price) ASC保证日均价格最低的记录排在第一位,price_rank = 1即可筛选出目标记录。 - 重复数据处理:原始数据存在重复销售记录,GROUP BY按商品、日期、门店分组后,
AVG(Sales_Price)会自动计算该分组下的真实平均价格,无需额外使用DISTINCT。
特殊情况处理(可选)
如果同一商品存在多个日期的日均价格相同且均为最低值,可将ROW_NUMBER()替换为RANK(),这样所有符合条件的记录都会被返回:
SELECT Grocery_Item, Month, Sales_Day, Sales_Date, Store_Name, Avg_Sales_Price FROM ( SELECT Grocery_Item, MONTH(Sales_Date) AS Month, Sales_Day, Sales_Date, Store_Name, ROUND(AVG(Sales_Price), 2) AS Avg_Sales_Price, RANK() OVER ( PARTITION BY Grocery_Item ORDER BY AVG(Sales_Price) ASC ) AS price_rank FROM Grocery_Data GROUP BY Grocery_Item, Sales_Date, Store_Name, Sales_Day ) ranked_data WHERE price_rank = 1;
内容的提问来源于stack exchange,提问作者A Girl Has No Name
相关产品推荐
相关产品推荐

