我想找到所有Foos
没有任何关联Bars
的 .
这是我正在使用的查询。它没有返回任何记录:
select * from foos f where f.id not in(select b.foo_id from bars b);
但是,我知道foo
with id = 1583
没有关联Bars
,因此在我之前的查询中应该至少有一个结果。
有人可以指出我犯的错误吗?谢谢。
我想找到所有Foos
没有任何关联Bars
的 .
这是我正在使用的查询。它没有返回任何记录:
select * from foos f where f.id not in(select b.foo_id from bars b);
但是,我知道foo
with id = 1583
没有关联Bars
,因此在我之前的查询中应该至少有一个结果。
有人可以指出我犯的错误吗?谢谢。
看起来不错;如果是我,我会怀疑错字。你检查过数据吗?
SELECT * from foos WHERE foos.id = 1583;
SELECT * from bars WHERE bars.foo_id = 1583;
我假设您已经从原来的语句中重新编写了您的语句以删除您的实际表名——因此请校对您的实际查询。
或尝试加入语法:
SELECT * FROM foos LEFT JOIN bars on foos.id = bars.foo_id WHERE bars.foo_id IS NULL;
原因是SQL三值逻辑。
示例:两个语句都会显示“?”。
SELECT CASE WHEN 2 NOT IN (3,4,NULL) THEN 'True' ELSE '?' END AS Test#0
SELECT CASE WHEN 2 <> 3 AND 2 <> 4 AND 2 <> NULL THEN 'True' ELSE '?' END AS Test#0
-- TRUE AND TRUE AND UNKNOWN => UNKNOWN (ELSE -> ?)
解决方案是使用 NOT EXISTS 而不是 NOT IN:
DECLARE @foo TABLE(foo_id INT);
INSERT @foo(foo_id)
SELECT 1 UNION ALL SELECT 2;
DECLARE @bars TABLE(bars_id INT IDENTITY(2,2), foo_id INT);
INSERT @bars(foo_id)
SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT NULL;
PRINT '@foo >'
SELECT * FROM @foo
PRINT '@bars >'
SELECT * FROM @bars
PRINT 'Test #1 >'
SELECT *
FROM @foo AS f
WHERE f.foo_id NOT IN (SELECT b.foo_id FROM @bars AS b)
PRINT 'Test #2 >'
SELECT *
FROM @foo AS f
WHERE NOT EXISTS (SELECT b.foo_id FROM @bars AS b WHERE b.foo_id = f.foo_id)
结果:
@foo >
foo_id
-----------
1
2
@bars >
bars_id foo_id
----------- -----------
2 3
4 4
6 NULL
Test #1 >
foo_id
-----------
Test #2 >
foo_id
-----------
1
2