如何查询foo表中未出现指定值的所有fk字段值?
解决方法:筛选完全没有指定值的FK
你的问题核心在于:原来的WHERE value <> 2只是排除了单条记录中value=2的行,但只要某个FK存在其他非2的记录,它还是会被选出来。我们需要的是整个FK的所有记录里都从未出现过value=2的结果,这里有几种靠谱的解法:
方法1:使用NOT EXISTS子查询(最直观的逻辑)
这种写法直接对应你的需求:找到所有不存在对应value=2记录的FK:
SELECT DISTINCT fk FROM foo f1 WHERE NOT EXISTS ( SELECT 1 FROM foo f2 WHERE f2.fk = f1.fk AND f2.value = 2 );
DISTINCT用来去重(如果你的FK有重复记录的话,不加也能得到正确结果,但加上更严谨)- 子查询会检查当前FK是否存在value=2的记录,不存在就保留该FK
方法2:GROUP BY + HAVING(分组统计判断)
通过分组后统计每个FK的value=2出现次数,筛选次数为0的:
SELECT fk FROM foo GROUP BY fk HAVING SUM(CASE WHEN value = 2 THEN 1 ELSE 0 END) = 0;
或者用MAX简化逻辑:
SELECT fk FROM foo GROUP BY fk HAVING MAX(CASE WHEN value = 2 THEN 1 ELSE 0 END) = 0;
- 第一种用SUM统计每个FK中value=2的出现次数,次数为0说明从未出现
- 第二种用MAX判断:如果有value=2的记录,MAX会返回1,否则返回0,等于0就是符合条件的FK
方法3:LEFT JOIN + IS NULL(关联筛选无匹配的记录)
通过左关联自身,找到没有匹配到value=2的FK:
SELECT DISTINCT f1.fk FROM foo f1 LEFT JOIN foo f2 ON f1.fk = f2.fk AND f2.value = 2 WHERE f2.fk IS NULL;
- 左关联会保留f1的所有记录,当f2中没有对应FK且value=2的记录时,f2的字段会是NULL
- 通过
WHERE f2.fk IS NULL就能筛选出那些从未有过value=2的FK
这三种方法在大多数数据库中都能正常工作,性能上NOT EXISTS和LEFT JOIN通常会被数据库优化器处理得差不多,具体可以根据你的数据库类型和数据量选择。
内容的提问来源于stack exchange,提问作者Black
相关产品推荐
相关产品推荐

