标签归档:not in注意事项

mssql sqlserver not in查询数据遇到的坑


摘要:
下文讲述sql脚本查询中,not in查询所遇到的坑及避免方法
实验环境:sql server 2008 R2


今天在使用not in 脚本检索数据时,发现有些数据并没有查询出来,通过仔细测试观察,发现是由于列值存在null,所导致的,下文将记载此类现象,
避免以后出现此类情况。

   create table [maomao365.com]
(keyId int identity(1,1),
 info  varchar(300) null )
go
insert into [maomao365.com]
(info)values('sqlblog'),(null),
('sqlserver'),('other'),
('sql'),(null)
go

select * from [maomao365.com] 
where info not in (
 'sqlblog','sql')
 
go
truncate table [maomao365.com]
drop     table [maomao365.com]

从上例的输出中,我们可以看出,只返回了两条数据,info等于null的数据未返回到数据库中,
那么可以证实not in数据检索,并不能返回列值为null的数据



为避免此类异常,我们有两种方法处理此异常:
方法1:在表设计时,避免所有列出现null值
方法2:在数据操作或检索时,对null列值进行单独处理,例:
select * from [maomao365.com]
where
(
info not in (‘sqlblog’,’sql’)
or info is null
)

mssql sqlserver sql脚本中替代not in关键字的方法分享


摘要:
下文通过举例的方式分享,sql脚本中替代not in关键字的写法,如下所示:
实验环境:sql server 2008 R2


常常在编写返回一张表中指定列不在另一张表的写法中时,我们使用最简便的方法如下所示:

 select * from tableNameA 
   where [列名] not in 
   ( 
     select [列名] from tableNameB
      where ...
   )

大家常说这种写法效率低下(未做实验证明),下面讲述一种改写not in 的写法,如下所示:
例:
表 maomaoA
拥有keyId和info两列
表 maomaoB
拥有keyId 和 infoB两列

当我们不想使用 not in 关键字时,我们可以采用连接的方式操作,如下
select a.keyId,a.info from maomaoA a
where exists (
select * from maomaoB b where b.keyId = a.keyId
)

mssql sqlserver in 关键字在值为null的应用举例


摘要:
下文通过案例分析in 关键字在值为null的应用举例,
分析出not in关键字在null值产生的异常信息
如下所示:

CREATE TABLE testA(keyId INT)
CREATE TABLE testB(keyId INT)
GO
INSERT INTO testA(keyId) VALUES (1)
INSERT INTO testA(keyId) VALUES (2)
INSERT INTO testA(keyId) VALUES (3)
GO
INSERT INTO testB(keyId) VALUES (1)
INSERT INTO testB(keyId) VALUES (2)
INSERT INTO testB(keyId) VALUES (4)
INSERT INTO testB(keyId) VALUES (NULL)
GO
 SELECT * FROM testA WHERE keyId IN (SELECT keyId FROM testB)
-----输出------
/*
keyId
1
2
*/
 SELECT * FROM testA WHERE keyId not IN (SELECT keyId FROM testB)
------无输出记录-----
/*
keyId
*/
INSERT INTO testA VALUES (NULL) ---在testA表中插入空值
SELECT * FROM testA WHERE EXISTS(
	SELECT null  FROM testB WHERE testA.keyId=testB.keyId	
)
----输出----
/*
keyId
1
2
*/
SELECT * FROM testA WHERE not  EXISTS(
	SELECT null  FROM testB WHERE testA.keyId=testB.keyId	
)
/*
keyId
3
NULL
*/
SELECT * FROM testA WHERE testA.keyId NOT in (
	SELECT testB.keyId FROM testB WHERE testB.keyId IS NOT NULL	
)

drop table testA
drop table testB


通过以上测试,我们可以看出not in 查询关键字如果子表中存在空值,则无法查询出任何记录,会导致异常产生,
需使用not exists获取相应的空值信息