【问题标题】:TSQL: NULL in the "IN" clauseTSQL:“IN”子句中的 NULL
【发布时间】:2011-12-16 22:01:16
【问题描述】:

我需要过滤以下记录:

NotificationRead = 0 || NULL --> IF GetRead = 0
NotificationRead = 1 --> IF GetRead = 1
NotificationRead = 0 || 1 || NULL --> IF GetRead = NULL

这是我为此使用的查询:

DECLARE @GetRead BIT
DECLARE @Query VARCHAR(20)

SET @GetRead = NULL

IF @GetRead = 0 SET @Query = '0,NULL'
ELSE IF @GetRead = 1 SET @Query = '1'
ELSE SET @Query = '0,1,NULL'

SELECT * FROM vwNotifications  WHERE NotificationRead IN (@Query)

当我在IN 子句中提供NULL 时,上面的查询基本上会失败。 感谢this question,我确实知道原因。

但是,如果我采用该问题的答案中建议的方法(使用NotificationRead IN (@Query) OR NotificationRead IS NULL),我会在我不需要它们时获得所有记录在NotificationRead = NULL 的位置,例如,当@GetRead = 1

你能告诉我正确的方向吗?

【问题讨论】:

  • 您不能在IN 类中使用NULL,因为NULLs 无法与SQL Server 上下文中的其他值/变量进行比较。例如,以下语句将不返回任何内容:SELECT * FROM [dbo].[TEST] WHERE [TestColumn] IN (NULL)

标签: sql sql-server tsql sql-server-2008


【解决方案1】:

您可以在查询顶部添加 SET ANSI NULLS OS。添加NULL时可以使用IN(NULL)子句。

SET ANSI NULLS OFF
SELECT * ......
....
WHERE UserId IN (1, 2, NULL)

【讨论】:

    【解决方案2】:

    几个选项:

    DECLARE @T TABLE (ID INT IDENTITY(1,1), Notify INT)
    DECLARE @GetRead BIT
    SET @GetRead = 0
    
    INSERT INTO @T
            ( Notify )
    VALUES  ( 0  -- Notify - int
              )
    
    INSERT INTO @T
            ( Notify )
    VALUES  ( 1  -- Notify - int
              )
    
    INSERT INTO @T
            ( Notify )
    VALUES  ( NULL  -- Notify - int
              )
    
    SELECT *
    FROM @t t
    WHERE @GetRead IS NULL 
        OR (@GetRead = 0 AND (t.Notify =0 OR t.Notify IS NULL))
        OR (@getRead = 1 AND t.Notify = @GetRead)
    
    SELECT *
    FROM @t t
    WHERE @GetRead IS NULL 
        OR ISNULL(t.notify, 0) = @GetRead
    

    【讨论】:

      【解决方案3】:

      其他人可能有更好的方法,但我会将您的选择移到每个“if”语句中,并进行相应的修改。

      IF @GetRead = 0
          SELECT * FROM vwNotifications WHERE NotificationRead IS NULL or NotificationRead = 0
      ELSE IF @GetRead = 1 
          SELECT * FROM vwNotifications WHERE NotificationRead = 1
      ELSE
          SELECT * FROM vwNotifications WHERE NotificationRead IS NULL or NotificationRead in 0, 1
      

      注意:请不要在生产代码中实际使用SELECT *。为您的列命名。

      【讨论】:

        【解决方案4】:

        不,问题是您将值作为字符串提供。

        1 IN (1, 2) -- true.
        1 IN ('1, 2') -- false.
        

        试试这个:

        SELECT *
        FROM vwNotifications 
        WHERE (@GetRead = 0 AND (NotificationRead = 0 OR NotificationRead IS NULL))
        OR    (@GetRead = 1 AND NotificationRead = 1)
        OR    (@GetRead IS NULL AND (NotificationRead IN (0, 1) OR 
                                     NotificationRead IS NULL))
        

        【讨论】:

          猜你喜欢
          • 2011-11-05
          • 1970-01-01
          • 2021-04-06
          • 2010-09-12
          • 2011-09-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多