如何编写SQL语句筛选所有记录均在上月添加的客户ID
需求说明
我有一张包含客户ID、商品和添加日期的表,表结构及数据如下:
| ID | Cust_ID | Item | DateAdded |
|---|---|---|---|
| 1 | Cust_1 | Handle | 2022-12-05 11:51:28.973 |
| 2 | Cust_1 | Foot | 2022-12-02 14:43:36.407 |
| 3 | Cust_1 | Door | 2022-12-02 14:42:20.727 |
| 4 | Cust_2 | Handle | 2022-10-10 13:07:49.640 |
| 5 | Cust_2 | Door | 2022-09-15 12:09:13.820 |
| 6 | Cust_2 | Leg | 2022-12-02 11:02:43.110 |
| 7 | Cust_3 | Handle | 2022-07-01 15:31:28.547 |
| 8 | Cust_3 | Door | 2022-12-06 10:26:56.987 |
需要编写一条SELECT语句,仅返回所有商品记录均在上月添加的客户ID。比如Cust_1的所有采购都在上月,应该返回;而Cust_2和Cust_3存在其他月份的记录,不应返回。预期结果如下:
| Cust_ID |
|---|
| Cust_1 |
我已经梳理好日期范围,尝试过多种GROUP BY和HAVING子句,但因为涉及日期而非字符串,遇到了困难。
解决方案
核心思路:筛选出所有记录的日期都完全落在上个月区间内的客户,可通过两种方式实现:
方法1:GROUP BY + HAVING 校验日期区间
通过分组客户ID,校验该组内所有记录的最小、最大日期是否都处于上个月范围内:
MySQL 写法
SELECT Cust_ID FROM your_table_name GROUP BY Cust_ID HAVING MIN(DateAdded) >= DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%Y-%m-01') AND MAX(DateAdded) < DATE_FORMAT(CURRENT_DATE, '%Y-%m-01');
SQL Server 写法
SELECT Cust_ID FROM your_table_name GROUP BY Cust_ID HAVING MIN(DateAdded) >= DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) - 1, 0) AND MAX(DateAdded) < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0);
PostgreSQL 写法
SELECT Cust_ID FROM your_table_name GROUP BY Cust_ID HAVING MIN(DateAdded) >= date_trunc('month', current_date - interval '1 month') AND MAX(DateAdded) < date_trunc('month', current_date);
方法2:NOT EXISTS 排除不符合条件的客户
查询不存在任何一条记录超出上个月范围的客户:
通用适配写法(以MySQL为例)
SELECT DISTINCT Cust_ID FROM your_table_name t1 WHERE NOT EXISTS ( SELECT 1 FROM your_table_name t2 WHERE t2.Cust_ID = t1.Cust_ID AND (t2.DateAdded < DATE_FORMAT(CURRENT_DATE - INTERVAL 1 MONTH, '%Y-%m-01') OR t2.DateAdded >= DATE_FORMAT(CURRENT_DATE, '%Y-%m-01')) );
说明
- 日期区间逻辑:上个月的第一天(包含)到本月的第一天(不包含),精准覆盖上个月所有时间。
- 替换代码中的
your_table_name为实际表名即可执行。
内容的提问来源于stack exchange,提问作者sbendall
相关产品推荐
相关产品推荐

