【问题标题】:SQL Server: NOT IN in where clause not working with NVARCHARSQL Server:NOT IN in where 子句不能与 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 都不为空。
  • Chanukya 的回答是正确的(他是第一个写出正确解决方案的人,所以 +1),他没有解释为什么 NOT IN 条件没有返回结果。原因是PARENT_PNAME 的某些值是空的,所以它们不能在NOT IN 运算符中使用。这将始终返回 false。
  • 我不太确定您要应用的标准是什么 - 返回您提到的两行有不同的标准。

标签: sql-server sql-server-2008 sql-server-2008-r2 notin


【解决方案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
          

          【讨论】:

            猜你喜欢
            • 2011-03-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-01-31
            • 2011-03-28
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多