如何查询有合同但缺失Service=1关联记录的客户?
需求:筛选有合同但无Service=1记录的客户
我有一张Client表,部分客户存在合同编号。目前正在执行一致性检查,确保Services表中存在对应合同客户的Service=1记录,需要构建SQL查询,筛选出Contract字段非空且未匹配到对应Service=1记录的客户。
Client表结构及数据
| id | Contract |
|---|---|
| 1 | C01 |
| 2 | C02 |
| 3 | C03 |
| 4 |
Services表结构及数据(需匹配Service=1)
| id | ClientID | Service |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 2 |
| 7 | 3 | 3 |
| 8 | 4 | 2 |
| 9 | 4 | 3 |
目标结果
仅需显示客户3,因为其有非空合同但无Service=1的关联记录。期望输出如下:
| id | Contract | id | ClientID | Service |
|---|---|---|---|---|
| 3 | C03 | null | null | null |
之前已能查询到有Service=1的客户,但无法找出缺失该记录的客户,尝试反向JOIN也未解决问题。
解决方案1:LEFT JOIN 结合 IS NULL 筛选
SELECT c.*, s.* FROM Client c LEFT JOIN Services s ON c.id = s.ClientID AND s.Service = 1 WHERE c.Contract IS NOT NULL AND s.ClientID IS NULL;
逻辑说明:通过LEFT JOIN保留所有Contract非空的客户记录,仅匹配Services表中Service=1的条目。当某个客户没有对应Service=1的记录时,Services表的所有字段会返回NULL,通过s.ClientID IS NULL即可筛选出这类客户。
解决方案2:使用NOT EXISTS子查询
SELECT c.id, c.Contract, NULL AS id, NULL AS ClientID, NULL AS Service FROM Client c WHERE c.Contract IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM Services s WHERE s.ClientID = c.id AND s.Service = 1 );
逻辑说明:直接检查当前客户是否不存在Service=1的关联记录,子查询仅需返回存在性标识(SELECT 1),执行效率较高,结果与需求完全匹配。
内容的提问来源于stack exchange,提问作者Mighty
相关产品推荐
相关产品推荐

