基于SQL的滚动3个月销售统计及最新购买商品查询需求
没问题,我给你写一个能满足需求的SQL语句,还会拆解关键逻辑,方便你根据实际情况调整:
目标SQL查询语句
SELECT c.CID, c.CustName, -- 处理无购买记录的情况,默认显示0 COALESCE(purchase_stats.total_purchases, 0) AS total_purchases_last_3months, -- 无购买时显示提示文本 COALESCE(last_purchase.latest_product, '该时间段无购买记录') AS latest_product_description FROM Customers c LEFT JOIN ( -- 统计每个客户近3个月的购买总数 SELECT CID, COUNT(*) AS total_purchases FROM Sales WHERE PurchDate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH) GROUP BY CID ) purchase_stats ON c.CID = purchase_stats.CID LEFT JOIN ( -- 找出每个客户近3个月内最后一次购买的商品 SELECT CID, CONCAT(Make, ' ', Model) AS latest_product FROM ( SELECT CID, Make, Model, PurchDate, -- 按客户分组,购买日期倒序排,标记最新的那条记录 ROW_NUMBER() OVER (PARTITION BY CID ORDER BY PurchDate DESC) AS rn FROM Sales WHERE PurchDate >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH) ) ranked_sales WHERE rn = 1 ) last_purchase ON c.CID = last_purchase.CID;
关键逻辑拆解:
- 动态时间范围:用
DATE_SUB(CURDATE(), INTERVAL 3 MONTH)自动计算当前日期往前推3个月的时间点,这样每次执行查询都是最新的3个月范围。如果你需要固定某个时间段(比如示例里的2018年1-3月),直接把WHERE条件换成PurchDate BETWEEN '2018-01-01' AND '2018-03-01'就行。 - 购买数量统计:子查询
purchase_stats专门用来按客户分组计数,统计近3个月的购买次数。 - 最新商品获取:内层用
ROW_NUMBER()窗口函数,给每个客户的购买记录按日期从新到旧排号,取排号为1的那条,再把品牌和型号拼接成商品描述。 - 兼容无购买的客户:用
LEFT JOIN确保所有客户都出现在结果里,COALESCE用来处理空值,避免结果里出现NULL,让报表更友好。
用你给的示例数据测试(假设当前日期是2018-03-01):
会得到这样的结果:
| CID | CustName | total_purchases_last_3months | latest_product_description |
|---|---|---|---|
| 001 | John | 3 | Ford Focus |
| 002 | Marty | 0 | 该时间段无购买记录 |
| 003 | Roger | 0 | 该时间段无购买记录 |
(解释下:John在2018年1-2月的3次购买都在近3个月里,最后一次是Ford Focus;Marty的购买在2017年12月,超出范围;Roger没有任何购买记录,所以都显示0和提示文本。)
内容的提问来源于stack exchange,提问作者user3783407
相关产品推荐
相关产品推荐

