按区域筛选TOP畅销产品:现有SQL查询的优化需求
按区域筛选最畅销产品的SQL优化方案
原SQL已实现按区域+产品维度统计累计销量:
SELECT soh.TerritoryID, sod.ProductID, SUM(OrderQty) AS Quantity FROM Sales.SalesOrderDetail sod INNER JOIN Sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderID GROUP BY sod.ProductID, soh.TerritoryID
下面提供两种实用的优化方案,帮你快速获取各区域的TOP畅销产品:
方案一:用窗口函数(推荐,适配主流数据库)
这是最简洁高效的方式,支持SQL Server、MySQL 8.0+、PostgreSQL等主流数据库。如果要保留并列第一的产品,可调整排名函数:
WITH RankedProducts AS ( SELECT soh.TerritoryID, sod.ProductID, SUM(OrderQty) AS Quantity, -- 按区域分组,销量越高排名越靠前 ROW_NUMBER() OVER (PARTITION BY soh.TerritoryID ORDER BY SUM(OrderQty) DESC) AS SalesRank FROM Sales.SalesOrderDetail sod INNER JOIN Sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderID GROUP BY sod.ProductID, soh.TerritoryID ) SELECT TerritoryID, ProductID, Quantity FROM RankedProducts WHERE SalesRank = 1;
- 用
ROW_NUMBER()时,同一区域若有多个产品销量并列第一,只会返回其中一个 - 若要保留所有并列第一的产品,把
ROW_NUMBER()换成RANK()(并列占同一名次,后续名次跳号)或DENSE_RANK()(并列占同一名次,后续名次不跳号)
方案二:关联子查询(适配老版本数据库)
如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用这种方式:
SELECT main.TerritoryID, main.ProductID, main.Quantity FROM ( -- 先统计各区域各产品的累计销量 SELECT soh.TerritoryID, sod.ProductID, SUM(OrderQty) AS Quantity FROM Sales.SalesOrderDetail sod INNER JOIN Sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderID GROUP BY sod.ProductID, soh.TerritoryID ) main -- 匹配当前区域销量最高的产品 WHERE main.Quantity = ( SELECT MAX(sub.Quantity) FROM ( SELECT SUM(sod_sub.OrderQty) AS Quantity FROM Sales.SalesOrderDetail sod_sub INNER JOIN Sales.SalesOrderHeader soh_sub ON sod_sub.SalesOrderID = soh_sub.SalesOrderID WHERE soh_sub.TerritoryID = main.TerritoryID GROUP BY sod_sub.ProductID ) sub );
注意:这种方式性能不如窗口函数,数据量大时优先选方案一。
内容的提问来源于stack exchange,提问作者ELavicount
相关产品推荐
相关产品推荐

