SQL - 不在另一个表中的记录

时间:2015-12-11 16:54:07

标签: sql-server tsql

在做我认为是在一个表中找不到另一个表中不存在的记录的相当常规的任务时,我开始如下。注意:公共值在一个表中是float类型(因此是cast),另一个是varchar(20)。 MEMID = float,DMID = varchar。

select cast((convert(int, MEMID)) as varchar(20))
from tempProv111315
where cast((convert(int, MEMID)) as varchar(20)) NOT IN (
     SELECT DMID
     FROM tempMemberMaster121015
)

上面没有记录(即使我知道一些已经存在)。因此,我尝试了以下(有效)。

select cast((convert(int, pv.MEMID)) as varchar(20))
from tempProv111315 pv
left outer join  tempMemberMaster121015 mm on
   cast((convert(int, pv.MEMID)) as varchar(20)) = mm.dmid
where mm.dmid is null

虽然可能是一个简单的原因,但对于我的生活,我不明白为什么第一种方式不起作用。我不是dba,但在不同情况下经常使用这两种方式,所以我真的想了解我所缺少的东西。任何人都可以解释不同的结果,因为他们 似乎 在逻辑上等于我。

ps - 我熟悉几种施放浮子的方法。这是我的典型方法。我不相信这是问题......但如果是这样,为什么它在第二个声明中没有用呢?

谢谢!

2 个答案:

答案 0 :(得分:4)

它是一种已知行为,您的子查询将返回NULL,这会导致not in失败。更多信息可以在here

找到
NOT IN
(
     SELECT DMID -- check whether this returns any NULL value
     FROM tempMemberMaster121015
)

我建议您使用NOT EXIST代替Left Outer Join

答案 1 :(得分:1)

您可以在SQL Server中使用EXCEPT查询从一个查询的结果中返回不在第二个查询结果中的不同行。

语法为:

{ <query_specification> | ( <query_expression> ) } 
EXCEPT 
{ <query_specification> | ( <query_expression> ) }

在您的问题中使用表格/查询的示例:

SELECT CAST((CONVERT(INT, MEMID)) AS VARCHAR(20)) from tempProv111315  
EXCEPT
SELECT DMID FROM tempMemberMaster121015

注意:对于其他数据库系统:在Oracle中,关键字为MINUS而不是EXCEPT。在MySQL中没有EXCEPT运算符,我也不相信PostgreSQL。但是,Gokhan Atil有一个描述how to implement the behavior of EXCEPT的帖子,顺便提一下,你在问题中找到了成功的LEFT OUTER JOIN查询。