ГДЕ поле1 В (НУЛЕВОЕ)

Я хочу получить данные из таблицы на основе нескольких столбцов, некоторые с данными, другие с 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'

Любая помощь будет оценена по достоинству.

В ОТВЕТ НА ПРЕДЛОЖЕНИЕ Джейви НИЖЕ: Это не делает того, что было задумано, или я делаю что-то не так!

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

person Pierre Cornelissen    schedule 11.07.2014    source источник


Ответы (3)


Попробуйте IS NULL

SELECT * FROM XYZ 
WHERE col1 IN ('a', 'b') 
AND col2 IN ('c', 'd') 
AND col3 IS NULL   -- Instead of IN (NULL)
person Dominic Zukiewicz    schedule 11.07.2014
comment
Любой из трех столбцов может иметь нулевое значение. Взгляните на последние три строки последней части кода, любая из этих трех переменных, которая является строкой с разделителями, может быть нулевой. - person Pierre Cornelissen; 11.07.2014

для каждого столбца проверьте его по вашему параметру и включите тест 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) используется для демонстрации параметра, который не был предоставлен

person Paul Maxwell    schedule 11.07.2014

что-то вроде этого должно работать:

SELECT * FROM XYZ
WHERE ISNULL(col1,'') IN ('a', 'b','')
AND   ISNULL(col2,'') IN ('c', 'd','')
AND   ISNULL(col3,'') IN ('')
person Jayvee    schedule 11.07.2014
comment
Хотя этот блок кода может ответить на вопрос, было бы лучше, если бы вы могли дать небольшое объяснение, почему это происходит. - person PlasmaHH; 11.07.2014
comment
@PlasmaHH, функция isnull будет оценивать нулевые значения до значения во втором параметре, в данном случае пустой строки (''). В отличие от null=null, которое оценивается как false, ''='' оценивается как true. - person Jayvee; 11.07.2014
comment
@Jayvee, я пробовал код, но он не работает. См. мой отредактированный вопрос выше - возможно, я делаю что-то не так. - person Pierre Cornelissen; 11.07.2014
comment
вам нужно включить '' как другое значение IN: WHERE ISNULL (значение,'') IN ('4','') AND ISNULL (значение2,'') IN ('4','') - person Jayvee; 11.07.2014