TSQL: "IN"子句中的NULL

3

我需要筛选记录,条件如下:

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时会失败。我通过这个问题知道了其中的原因。
但是,如果我采用该问题答案中建议的方法(使用NotificationRead IN (@Query) OR NotificationRead IS NULL),则会获取所有记录,即使我不需要它们,例如当@GetRead = 1时,也会获取NotificationRead = NULL的记录。
请问你能指导我正确的方向吗?

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

6
不,问题在于您提供的是字符串值。
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))

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 *。给你的列命名。

0

有几个选项:

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

0

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接