SQL查询:筛选符合条件且无对应Call类型记录的Customer_ID
如何筛选符合条件且无特定类型记录的客户ID?
示例数据
| Customer_ID | CaseType | CaseStatus | DateOpened | DateClosed |
|---|---|---|---|---|
| 100 | Letter | Letter | 01/01/2023 | 01/03/2023 |
| 100 | Call | Call | 01/02/2023 | 01/04/2023 |
| 200 | Letter | Letter | 01/01/2023 | 01/03/2023 |
需求
返回满足以下条件的Customer_ID:
- 存在
CaseType = 'Letter'且DateClosed = '01/03/2023'的记录 - 该客户没有任何
CaseType = 'Call'的记录
示例中仅需返回Customer_ID = 200,因为客户100存在Call类型记录,需排除。
我的尝试
我写了以下SQL语句:
SELECT DISTINCT Customer_ID WHERE CaseType = 'Letter' AND DateClosed = '01/03/2023'
但它返回了100和200,无法实现排除有Call类型记录的客户的逻辑,求技术指导。
解决方案
方法1:使用NOT EXISTS子查询
这是最直观且性能较好的方案,先筛选符合Letter条件的客户,再排除存在Call记录的客户:
SELECT DISTINCT c1.Customer_ID FROM your_table_name c1 WHERE c1.CaseType = 'Letter' AND c1.DateClosed = '01/03/2023' AND NOT EXISTS ( SELECT 1 FROM your_table_name c2 WHERE c2.Customer_ID = c1.Customer_ID AND c2.CaseType = 'Call' );
说明:子查询检查当前客户是否有Call类型记录,NOT EXISTS确保仅保留无此类记录的客户。
方法2:使用LEFT JOIN + IS NULL
通过左连接匹配Call记录,筛选未匹配到的客户:
SELECT DISTINCT c1.Customer_ID FROM your_table_name c1 LEFT JOIN your_table_name c2 ON c1.Customer_ID = c2.Customer_ID AND c2.CaseType = 'Call' WHERE c1.CaseType = 'Letter' AND c1.DateClosed = '01/03/2023' AND c2.Customer_ID IS NULL;
说明:左连接保留所有符合Letter条件的客户,有Call记录的客户会匹配到c2的数据,无记录的c2字段为NULL,通过c2.Customer_ID IS NULL筛选目标客户。
方法3:使用EXCEPT(适用于SQL Server、PostgreSQL等)
先获取符合Letter条件的客户列表,再减去存在Call记录的客户列表:
SELECT DISTINCT Customer_ID FROM your_table_name WHERE CaseType = 'Letter' AND DateClosed = '01/03/2023' EXCEPT SELECT DISTINCT Customer_ID FROM your_table_name WHERE CaseType = 'Call';
说明:EXCEPT返回第一个查询有但第二个查询没有的记录,正好满足需求。
性能优化提示
你的表有6万条记录,建议给Customer_ID和CaseType建立联合索引,能大幅提升以上查询的执行效率。其中NOT EXISTS通常是性能最优的选择,多数数据库会对其做优化。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

