如何编写多条件嵌套查询?按不同时间范围统计Top产品与客户
调整Top150产品与对应Top10客户的统计日期范围方案
我来帮你修改这段SQL代码,核心思路是拆分两个独立的统计逻辑:先用10年历史数据筛选出Top150产品,再针对这些产品单独用2年历史数据统计各自的Top10客户,最后把两者关联起来得到目标报表。
完整实现代码
-- 第一步:用10年历史数据筛选Top150产品 WITH top_150_products AS ( SELECT product_id, SUM(sales_amount) AS product_sales, DENSE_RANK() OVER (ORDER BY SUM(sales_amount) DESC, product_id) AS product_rank FROM Sales_details -- 过滤10年历史数据,假设日期字段为sale_date,可根据实际字段调整 WHERE sale_date >= DATEADD(YEAR, -10, GETDATE()) GROUP BY product_id HAVING product_rank <= 150 ), -- 第二步:针对Top150产品,用2年历史数据统计每个产品的Top10客户 product_top_10_customers AS ( SELECT sd.product_id, sd.customer_id, SUM(sd.sales_amount) AS customer_sales, DENSE_RANK() OVER (PARTITION BY sd.product_id ORDER BY SUM(sd.sales_amount) DESC, sd.customer_id) AS customer_rank FROM Sales_details sd JOIN top_150_products tp ON sd.product_id = tp.product_id -- 过滤2年历史数据 WHERE sd.sale_date >= DATEADD(YEAR, -2, GETDATE()) GROUP BY sd.product_id, sd.customer_id HAVING customer_rank <= 10 ) -- 第三步:关联结果,输出最终报表 SELECT tp.product_id, tp.product_sales, tp.product_rank, ptc.customer_id, ptc.customer_sales, ptc.customer_rank FROM top_150_products tp JOIN product_top_10_customers ptc ON tp.product_id = ptc.product_id ORDER BY tp.product_rank, ptc.customer_rank;
关键细节说明
- 日期适配:如果你的数据库不是SQL Server,需要替换日期计算函数,比如MySQL用
DATE_SUB(CURDATE(), INTERVAL 10 YEAR),Oracle用SYSDATE - INTERVAL '10' YEAR,根据实际数据库类型调整。 - 排名选择:
DENSE_RANK()会给销售额相同的产品/客户相同排名,如果你需要严格的唯一序号,可以换成ROW_NUMBER(),根据业务需求灵活调整。 - CTE结构:用公共表表达式拆分逻辑,让代码更清晰易读,后续修改日期范围或排名规则时也更方便。
内容的提问来源于stack exchange,提问作者vinnynh
相关产品推荐
相关产品推荐

