简单SQL查询中的“不在”问题

简单SQL查询中的“不在”问题,sql,sql-server-2005,Sql,Sql Server 2005,我需要从旧表中找到新表中不存在的所有id 为什么这个查询找不到id SELECT old_id FROM OldTable WHERE old_id NOT IN ( SELECT id FROM NewTable) 由他们自己,他们返回这个 --Returns the id 18571 SELECT old_id FROM OldTable WHERE old_id = 18571 --Returns nothing SELECT id FROM NewTable WHERE i

我需要从旧表中找到新表中不存在的所有id 为什么这个查询找不到id

SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)  
由他们自己,他们返回这个

--Returns the id 18571
SELECT old_id FROM OldTable WHERE old_id = 18571

 --Returns nothing  
SELECT id FROM NewTable WHERE id = 18571 
我是不是漏掉了什么明显的东西

这两列都是int类型和主键

解决

id列中有null,我只是不知道而已=/

这些工作:

SELECT old_id FROM OldTable EXCEPT SELECT id FROM NewTable  

SELECT * FROM old_table ot WHERE NOT EXISTS (
SELECT * FROM new_table nt WHERE nt.id = ot.old_id)  
这些不起作用:

SELECT old_id FROM OldTable LEFT JOIN NewTable ON old_id = id WHERE id IS NULL  

SELECT old_id FROM OldTable WHERE old_id NOT IN (
SELECT id FROM NewTable)
您在第一个查询的where条件中使用旧的\u id,在第二个查询中使用id

select oldtable.id as orginal, newtable.id as new 
from oldtable 
left outer join newtable 
on oldtable.id =newtable.id 
where new is null
AFAIK和我不是专家-检查我的代表;-左外连接是一种很好的技术。。它可能会执行not in,并且不需要子选择


@有一天,我善意地指出,情况并非总是如此,例如,在SQL Server EXISTS中可以更高效。

我不知道为什么您的查询没有给出所需的结果,但我知道,使用not in不是很有效。您最好使用连接:

SELECT old_id 
FROM OldTable 
LEFT JOIN NewTable
    ON old_id = id
WHERE id IS NULL

这种差异可归因于空值的存在

考虑这两个简化查询,注意两个查询的谓词均为NULL=1,其计算结果为未知,分别由notexists和notin处理:

SELECT *
  FROM OldTable
 WHERE NULL NOT IN (SELECT 1 FROM OldTable);

 SELECT *
  FROM OldTable
 WHERE NOT EXISTS (SELECT * FROM OldTable WHERE NULL = 1);
第一个不返回任何行,因为NOT IN子查询的计算结果为FALSE

第一个返回所有行,因为不存在计算为TRUE的子查询


结论:避免空值。

从新表中选择id可能会返回空值。这意味着您的查询不会返回任何结果。两列的数据类型是否完全相同。。您是否缺少强制转换或是一些小的格式调整?子查询不会返回任何空值。这两个表的id列上都没有设置NULL,您使用的是哪个数据库系统?您是直接使用SQLyog在数据库上执行查询,还是使用脚本?@Martin-谢谢,您的第一条评论是对的,id列中有null。当我查找NOTNULL设置时,我检查了错误的列。当我输入查询时,我犯了错误。效率不高-在什么方面,请记住您不需要;我甚至不知道他们使用的是哪种SQL产品?它将比不在-我注意到你的免责声明,但如果你甚至不知道他们使用的是哪种SQL产品,你怎么知道这一点?@onedaywhen非常好的观点。。只是听到说,这是我被告知的,分选择&不在=坏。这是否因产品/发动机而异?是的,除其他外。EXISTS对SQL Server很好,因为它可能会短路,但可能不是每次都是最好的。@onedaywhen哦,酷。。我会更新答案的价值。顺便说一句,你是不是被新的atusername autocomplete搞砸了或者这是我成为新手的另一个例子吗?是的,我确实经常被抓住,但在我的辩护中,这是一个相对较新的变化,我是一个老手;NOT in子查询和NOT EXISTS子查询之间的行为差异是由于存在null。他们说这些列不可为null。我怀疑他们遇到了与此处相同的问题@Martin Smith:但你是对的,它可能与你链接的问题是同一个问题,一个我自己没有遇到的问题,这确实会导致语法错误!所以谢谢你。
SELECT * FROM old_table ot
WHERE NOT EXISTS (
   SELECT * FROM new_table nt
   WHERE nt.new_key = ot.old_key
   );
SELECT *
  FROM OldTable
 WHERE NULL NOT IN (SELECT 1 FROM OldTable);

 SELECT *
  FROM OldTable
 WHERE NOT EXISTS (SELECT * FROM OldTable WHERE NULL = 1);