【问题标题】:WHERE field1 IN (NULL)WHERE field1 IN (NULL)
【发布时间】:2014-07-11 08:18:03
【问题描述】:

我想根据几列从表中检索数据,其中一些包含数据,另一些包含 NULL。在下面的第一个代码示例中,该过程很好 - 返回所有行。在第二个示例中,不返回任何行 - 因为 NULL=NULL 返回 FALSE。

第三个示例或多或少是我的想法,当列具有 NULL 值时,必须“忽略”该子句,并且仅使用前两列中的数据返回基于这些的行两列。

SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
AND col3 IN ('e', 'f')


SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
AND col3 IN (NULL) --???


SELECT * FROM XYZ
WHERE col1 IN ('a', 'b')
AND col2 IN ('c', 'd')
--AND col3 IN (NULL) --IGNORED

目前我使用的是动态SQL语句,但是很慢。

SET @EventCodeList = 
(SELECT REPLACE(tEventCode, ' ', '') FROM tblActivityPerCC_Config WHERE tCostCenter = @CostCenter) 


SET @EventCodeStr = 
CASE WHEN @EventCodeList IS NULL THEN ' logs.tEventCode LIKE (''%'') '
ELSE ' logs.tEventCode IN (SELECT qValue FROM nsEMV.dbo.fncReturnCommaDelimitedStringAsTable(@EventCodeList))'
END

SET @SQLString = N'  
SELECT
    ccg.Field1,
    logs.Field2     
FROM dbo.tblEMV_Logsheet AS logs 
INNER JOIN dbo.tblLookup_EMVEquipment AS ccg ON logs.tEquipmentKey = ccg.tEquipmentKey
WHERE tDate BETWEEN ''' + CONVERT(varchar(30), @BMonth) + ''' AND ''' + CONVERT(varchar(30), @EMonth) + ''' 
AND  logs.tAreaCode IN ('XYZ', 'ABC') 
AND ' + @EventCodeStr + ' --THE FOLLOWING COLUMNS MAY HAVE NULL VALUES
AND ' + @SourceStr + '
AND ' + @DestinationStr'

任何帮助将不胜感激。

针对 Jayvee 的以下建议: 这不符合预期或我做错了什么!

CREATE TABLE #temp
(
value varchar(10),
value2 varchar(10)
)

INSERT INTO #temp (value, value2) SELECT '5', '3'
INSERT INTO #temp (value, value2) SELECT NULL, '2'
INSERT INTO #temp (value, value2) SELECT '4', NULL
INSERT INTO #temp (value, value2) SELECT '6', '2'
INSERT INTO #temp (value, value2) SELECT '6', NULL
INSERT INTO #temp (value, value2) SELECT '6', '4'
INSERT INTO #temp (value, value2) SELECT NULL, '1'
INSERT INTO #temp (value, value2) SELECT NULL, '4'

SELECT value as [value],value2 as [value2]  FROM #temp
WHERE ISNULL(value,'') IN ('4')
AND ISNULL(value2,'') IN ('4')

DROP TABLE #temp

【问题讨论】:

    标签: tsql null where-in


    【解决方案1】:

    试试IS NULL

    SELECT * FROM XYZ 
    WHERE col1 IN ('a', 'b') 
    AND col2 IN ('c', 'd') 
    AND col3 IS NULL   -- Instead of IN (NULL)
    

    【讨论】:

    • 三列中的任何一列都可以有空值。看看最后一段代码的最后三行,这三个变量中的任何一个,即一个定界字符串,都可以为空。
    【解决方案2】:

    针对您的参数测试每一列并包括 IS NULL 测试,将这些与括号结合起来,如下所示:

    SELECT
          *
    FROM XYZ
    WHERE (col1 IN ('a', 'b') OR col1 IS NULL)
      AND (col2 IN ('c', 'd') OR col2 IS NULL) 
      AND (col3 IN (NULL) OR col3 IS NULL)
    

    这里col3 IN (NULL)用来演示一个没有提供的参数

    【讨论】:

      【解决方案3】:

      这样的事情应该可以工作:

      SELECT * FROM XYZ
      WHERE ISNULL(col1,'') IN ('a', 'b','')
      AND   ISNULL(col2,'') IN ('c', 'd','')
      AND   ISNULL(col3,'') IN ('')
      

      【讨论】:

      • 虽然这个代码块可能会回答这个问题,但最好能稍微解释一下为什么会这样。
      • @PlasmaHH isnull 函数会将空值评估为第二个参数中的值,在这种情况下为空字符串('')。与评估为 false 的 null=null 不同,''='' 评估为 true。
      • @Jayvee,我已经尝试了代码但不起作用。请参阅上面我编辑的问题 - 也许我做错了什么。
      • 您需要将 '' 作为另一个 IN 值: WHERE ISNULL(value,'') IN ('4','') AND ISNULL(value2,'') IN ('4' ,'')
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多