SQL Server:NOT IN in where 子句不能与 NVARCHAR 一起使用

Posted

技术标签:

【中文标题】SQL Server:NOT IN in where 子句不能与 NVARCHAR 一起使用【英文标题】:SQL Server: NOT IN in where clause not working with NVARCHAR 【发布时间】:2017-01-31 11:30:40 【问题描述】:

我有下表:

DECLARE @P AS TABLE
(
    ID int,
    PID  int,
    PNAME NVARCHAR(30),
    PARENT_PNAME NVARCHAR(30),
    Error int
)

INSERT INTO @P VALUES
(554,1,'AAAA',NULL,0),
(554,2,'BBBB',NULL,0),
(554,3,'CCCC',NULL,0),
(554,4,'DDDD','AAAA',0),
(554,5,'EEEE','AAAA',0),
(554,6,'FFFF',NULL,0),
(554,7,'GGGG',NULL,0),
(554,8,'HHHH',NULL,0),
(554,9,'IIII',NULL,0),
(554,10,'JJJJ',NULL,0),
(554,11,'KKKK',NULL,0);

如果我运行以下查询:

select ID, PID, PNAME, PARENT_PNAME,  Error
from   @P                  
where  PNAME not in (select PARENT_PNAME 
                     from   @P
                     where  PNAME is not null)
       AND PARENT_PNAME IS NOT NULL

我什么也得不到,没有结果。为什么“NOT IN”不起作用?

我需要获取以下两行:

(554,4,'DDDD','AAAA',0)
(554,5,'EEEE','AAAA',0)

【问题讨论】:

附带说明:对于您的示例数据,条件 where PNAME is not null 无效,因为所有 PNAME 都不为空。 NOT IN clause and NULL values的可能重复 Chanukya 的回答是正确的(他是第一个写出正确解决方案的人,所以 +1),他没有解释为什么 NOT IN 条件没有返回结果。原因是PARENT_PNAME 的某些值是空的,所以它们不能在NOT IN 运算符中使用。这将始终返回 false。 我不太确定您要应用的标准是什么 - 返回您提到的两行有不同的标准。 【参考方案1】:
DECLARE @P AS TABLE
(
    ID int,
    PID  int,
    PNAME NVARCHAR(30),
    PARENT_PNAME NVARCHAR(30),
    Error int
)

INSERT INTO @P VALUES
(554,1,'AAAA',NULL,0),
(554,2,'BBBB',NULL,0),
(554,3,'CCCC',NULL,0),
(554,4,'DDDD','AAAA',0),
(554,5,'EEEE','AAAA',0),
(554,6,'FFFF',NULL,0),
(554,7,'GGGG',NULL,0),
(554,8,'HHHH',NULL,0),
(554,9,'IIII',NULL,0),
(554,10,'JJJJ',NULL,0),
(554,11,'KKKK',NULL,0);

select * from @P where PARENT_PNAME is not null

输出

ID  PID PNAME   PARENT_PNAME    Error
554 4   DDDD    AAAA    0
554 5   EEEE    AAAA    0

【讨论】:

【参考方案2】:

您不需要NOT IN 子句。试试看:

SELECT * FROM  @P where PARENT_PNAME is NOT NULL

【讨论】:

【参考方案3】:

您还应该在嵌套查询中添加and PARENT_PNAME is not null

SELECT ID, PID, PNAME, PARENT_PNAME, Error
FROM @P
WHERE PNAME NOT IN (
        SELECT PARENT_PNAME
        FROM @P
        WHERE PNAME IS NOT NULL
            AND PARENT_PNAME IS NOT NULL
        )
    AND PARENT_PNAME IS NOT NULL

这就是你没有得到任何结果的原因。

对于more detailed information have a look here

【讨论】:

【参考方案4】:
select ID, PID, PNAME, PARENT_PNAME,  Error
from   @P                  
where  PNAME<>PARENT_PNAME
       AND PARENT_PNAME IS NOT NULL

当你有空值时不要使用 NotIN 进行比较,使用 NOT Exists

【讨论】:

【参考方案5】:

有多种方法可以获得所需的结果。

--method 1    
select ID, PID, PNAME, PARENT_PNAME,  Error
from   @P P1                 
where EXISTS (select PARENT_PNAME 
                 from   @P P2
                 where  p2.PNAME = p1.PNAME 
                        and P1.PARENT_PNAME is not null)

--query 2
select P1.* 
from @P  P1
where P1.PARENT_PNAME is not null

【讨论】:

以上是关于SQL Server:NOT IN in where 子句不能与 NVARCHAR 一起使用的主要内容,如果未能解决你的问题,请参考以下文章

ms sql2012 能否安装在win2008 server

Sql server2008! SQL server服务无法启动,并显示错误17113, 修复Sql server2008失败!

sql server 的考证问题

求sql server帮助文档

已安装 SQL Server 2005,安装 SQL Server 2008 时提示需要删除 SQL Server 2005 Express 工具

server 2008 r2能安装sql server 2016吗?