如何用SQL筛选同ID下Phone2与所有Phone1无匹配的记录?
问题描述
我有一张存储来自两个不同数据库的服务商及其手机号的表,需要找出同ID下,数据库2的手机号Phone2与数据库1的所有Phone1都不匹配的服务商。已知每个ID对应的Phone2唯一,而Phone1可以有多条。
表结构及数据
| ID | PHONE1 | PHONE2 |
|---|---|---|
| 1 | 5126078099 | 5129082933 |
| 1 | 5129082933 | 5129082933 |
| 2 | 9506079090 | 9504057890 |
| 2 | 9823939393 | 9504057890 |
| 3 | 7555769000 | 7552939302 |
| 3 | 7552939302 | 7552939302 |
预期结果
仅返回ID为2的服务商。
尝试的无效SQL
SELECT * FROM Table a WHERE a.PHONE2 NOT IN (SELECT b.PHONE1 FROM Table b WHERE a.ID = b.ID)
解决方案
你写的SQL无效的原因是:它是逐行判断的——只要某一行的Phone2不在当前ID的Phone1列表里,就会把这条记录选出来,但实际上你要的是整个ID下所有Phone1都和该ID的Phone2不匹配的情况,不是单条记录的判断。
下面提供几种可行的实现方式:
方法1:用NOT EXISTS做存在性验证
SELECT DISTINCT t.ID, t.PHONE2 FROM your_table t WHERE NOT EXISTS ( SELECT 1 FROM your_table t2 WHERE t2.ID = t.ID AND t2.PHONE1 = t.PHONE2 )
逻辑:检查当前ID下有没有任何一条Phone1等于Phone2的记录,如果没有,就说明这个ID的Phone2和所有Phone1都不匹配。用DISTINCT去重是因为每个ID对应多条记录,但Phone2唯一,去重后得到每个符合条件的ID和对应的Phone2。
方法2:分组后统计匹配数
SELECT ID, MAX(PHONE2) AS PHONE2 FROM your_table GROUP BY ID HAVING COUNT(CASE WHEN PHONE1 = PHONE2 THEN 1 END) = 0
逻辑:按ID分组,统计该ID下Phone1等于Phone2的记录数量。如果数量是0,就说明这个ID没有匹配的情况。因为每个ID的Phone2唯一,用MAX(PHONE2)就能取出该ID对应的Phone2值(用MIN也一样)。
方法3:自连接筛选无匹配的ID
SELECT DISTINCT t.ID, t.PHONE2 FROM your_table t LEFT JOIN your_table t2 ON t.ID = t2.ID AND t.PHONE2 = t2.PHONE1 WHERE t2.ID IS NULL
逻辑:把表和自己做左连接,关联条件是ID相同且Phone2等于Phone1。如果连接后t2.ID为NULL,说明这个ID下没有任何Phone1和Phone2匹配。最后用DISTINCT去重得到结果。
内容的提问来源于stack exchange,提问作者Ben Smith
相关产品推荐
相关产品推荐

