如何合并查询获取150个高销售额产品各Top10客户的销售数据
解决Top150产品对应各自Top10客户的SQL合并方案
嗨,我明白你现在的需求——把两个独立查询整合,拿到Top150产品 × 每个产品的Top10客户刚好1500条记录对吧?咱们用CTE(公共表表达式)来分层处理,逻辑清晰还容易维护,直接上方案:
核心思路
先筛选出总销售额排名前150的产品,再对每个产品下的客户销售额做排名,最后把这两个结果关联,只保留每个Top产品的前10位客户。
完整SQL示例
-- 第一步:获取按总销售额排名的前150个产品 WITH TopProducts AS ( SELECT product_ID, SUM(sales$) AS product_total_sales, -- 给产品按销售额降序排名 ROW_NUMBER() OVER(ORDER BY SUM(sales$) DESC) AS product_rank FROM your_sales_table -- 替换成你的实际销售表名 GROUP BY product_ID HAVING SUM(sales$) > 0 -- 可选:排除无销售记录的产品 -- 这里根据数据库类型调整取前150的方式: -- MySQL/LiteSQL用 LIMIT 150; -- SQL Server用 TOP 150 放在SELECT后面 -- Oracle用 FETCH FIRST 150 ROWS ONLY ), -- 第二步:统计每个产品下各客户的总销售额,并给客户在产品内排名 CustomerSalesRanking AS ( SELECT product_ID, custno, SUM(sales$) AS total_sal, -- 按产品分组,给客户按销售额降序排名 ROW_NUMBER() OVER(PARTITION BY product_ID ORDER BY SUM(sales$) DESC) AS customer_rank FROM your_sales_table GROUP BY product_ID, custno HAVING SUM(sales$) > 0 -- 可选:排除无购买记录的客户 ) -- 第三步:关联两个CTE,筛选出目标结果 SELECT tp.product_ID, tp.product_total_sales, csr.custno, csr.total_sal, tp.product_rank, csr.customer_rank FROM TopProducts tp INNER JOIN CustomerSalesRanking csr ON tp.product_ID = csr.product_ID WHERE csr.customer_rank <= 10 -- 只保留每个产品的前10客户 ORDER BY tp.product_rank, csr.customer_rank; -- 按产品排名+客户排名排序
关键细节说明
- 排名函数选择:我用了
ROW_NUMBER(),它会给销售额相同的客户分配不同的排名,确保每个产品刚好出10条记录。如果允许并列排名(比如两个客户销售额相同都算Top10,可能导致单产品超过10条),可以换成RANK()或DENSE_RANK(),根据你的业务需求调整。 - 数据库适配:不同数据库取前N条的语法不一样,注释里已经标了常见数据库的写法,记得对应修改。
- 字段/表名替换:把
your_sales_table换成你实际的销售数据表,字段名如果和示例不一致(比如custno是customer_id),也要同步调整。
内容的提问来源于stack exchange,提问作者vinnynh
相关产品推荐
相关产品推荐

