如何查询近3个月每月至少有1笔交易的客户?
实现近3个月每月至少1笔交易的客户查询
核心思路
要筛选出近3个月每个月都有交易的客户,关键是统计每个客户在目标时间段内覆盖了多少个不同的月份,当覆盖月份数等于3时,即为符合条件的客户。
针对SQL Server的实现代码
方式1:仅返回符合条件的客户ID
-- 定义近3个月的完整自然月范围(比如当前是6月,对应3、4、5月) WITH DateRange AS ( SELECT DATEADD(month, DATEDIFF(month, 0, GETDATE()) - 3, 0) AS StartDate, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AS EndDate ), CustomerMonthStats AS ( SELECT customerID, -- 提取交易所属的年月,用于按月份去重统计 FORMAT(transactionDate, 'yyyy-MM') AS TransactionMonth FROM transactions CROSS JOIN DateRange WHERE transactionDate >= StartDate AND transactionDate < EndDate -- 同一个客户同一月份只保留一条记录,避免重复统计 GROUP BY customerID, FORMAT(transactionDate, 'yyyy-MM') ) -- 筛选出覆盖了3个月份的客户 SELECT customerID FROM CustomerMonthStats GROUP BY customerID HAVING COUNT(DISTINCT TransactionMonth) = 3;
方式2:返回符合条件客户的所有交易记录
如果需要获取这些客户的全部交易数据,可通过IN子查询关联原表:
SELECT * FROM transactions WHERE customerID IN ( WITH CustomerMonthStats AS ( SELECT customerID, FORMAT(transactionDate, 'yyyy-MM') AS TransactionMonth FROM transactions WHERE transactionDate >= DATEADD(month, -3, GETDATE()) GROUP BY customerID, FORMAT(transactionDate, 'yyyy-MM') ) SELECT customerID FROM CustomerMonthStats GROUP BY customerID HAVING COUNT(DISTINCT TransactionMonth) = 3 );
调整说明
- 若你的“近3个月”需要包含当前月(比如当前是6月20日,对应4、5、6月),只需修改
DateRange中的StartDate为DATEADD(month, DATEDIFF(month, 0, GETDATE()) - 2, 0)即可。 - 如果你使用的是其他数据库(如MySQL),只需替换日期处理函数:比如
FORMAT换成DATE_FORMAT(transactionDate, '%Y-%m'),GETDATE()换成CURDATE(),DATEADD换成DATE_SUB。
内容的提问来源于stack exchange,提问作者Jeremy Ragsdale
相关产品推荐
相关产品推荐

