SQL查询需求:获取各门店销量最高商品及对应销量
解决每个门店销量最高商品的SQL查询问题
首先,先明确你的核心需求:从StoreRecords表中,统计每个门店的销量冠军商品(包含门店ID、商品名称、对应销量)。咱们先梳理下你现有语句里的小问题,再给出优化后的方案。
现有语句的问题点
- 语句里的
WHERE StoreGroupID = 1122是多余的——你的示例数据和需求里都没提到这个字段,会过滤掉不符合条件的数据,应该删掉。 - 内层子查询的
ORDER BY StoreID, Frequency没必要,内层排序对外层窗口函数的逻辑没有影响,反而会增加不必要的计算开销。 - 字段名有笔误:原表列名是
Product,但你写的是Products,会导致语法错误。 - 使用
ROW_NUMBER()的话,如果某个门店有多个商品销量并列第一,只会返回其中一个;如果需要保留所有并列冠军,得换成RANK()或者DENSE_RANK()。
优化后的SQL语句
场景1:每个门店只返回一个销量最高的商品(即使有并列)
这个场景用ROW_NUMBER()就合适,它会给每个门店分组内的行按销量降序编号,取编号为1的行:
SELECT StoreID AS "Store ID", Product, Frequency AS "Sales Volume" FROM ( SELECT StoreID, Product, COUNT(*) AS Frequency, ROW_NUMBER() OVER(PARTITION BY StoreID ORDER BY COUNT(*) DESC) AS Ordering FROM StoreRecords GROUP BY StoreID, Product ) ranked WHERE Ordering = 1;
场景2:保留所有销量并列最高的商品
如果需要把门店里所有和冠军销量相同的商品都列出来,就用RANK()(它会给相同销量的商品分配相同排名,跳过后续的排名编号):
SELECT StoreID AS "Store ID", Product, Frequency AS "Sales Volume" FROM ( SELECT StoreID, Product, COUNT(*) AS Frequency, RANK() OVER(PARTITION BY StoreID ORDER BY COUNT(*) DESC) AS Ordering FROM StoreRecords GROUP BY StoreID, Product ) ranked WHERE Ordering = 1;
验证示例数据
用你的示例数据测试场景1的语句,会得到和你期望完全一致的结果:
Store ID Product
1 Apple iPhone
2 Android phone
3 Apple iPhone
如果某个门店出现销量并列的情况(比如门店1的Apple iPhone和Android phone都卖了2次),场景2的语句会把两个商品都返回,而场景1只会返回其中一个(具体哪个取决于数据库的默认排序规则,因为销量相同时没有额外排序条件)。
内容的提问来源于stack exchange,提问作者dave
相关产品推荐
相关产品推荐

