WHERE NULL, NOT NULL или NO WHERE в зависимости от значения параметра SQL Server - PullRequest
30 голосов
/ 01 мая 2009

У меня есть хранимая процедура в SQL Server 2000, которая выполняет поиск на основе значений параметров. Для одного из переданных параметров мне нужно другое предложение WHERE в зависимости от его значения - проблема в том, что 3 значения будут где MyColumn

  1. IS NULL
  2. IS NOT NULL
  3. ANY VALUE (NULL AND NOT NULL) (по существу, не WHERE предложение)

У меня есть какой-то ментальный блок в выработке правильного синтаксиса. Возможно ли это сделать в одном операторе select без выполнения IF @parameter BEGIN ... END ветвления?

Ответы [ 6 ]

41 голосов
/ 01 мая 2009

Вот как вы можете решить эту проблему с помощью одного предложения WHERE:

WHERE (@myParm = value1 AND MyColumn IS NULL)
OR  (@myParm = value2 AND MyColumn IS NOT NULL)
OR  (@myParm = value3)

Наивное использование оператора CASE не работает , под этим я подразумеваю следующее:

SELECT Field1, Field2 FROM MyTable
WHERE CASE @myParam
    WHEN value1 THEN MyColumn IS NULL
    WHEN value2 THEN MyColumn IS NOT NULL
    WHEN value3 THEN TRUE
END

Эту проблему можно решить с помощью оператора case, см. Один раз, когда ответ

13 голосов
/ 01 мая 2009

Вы могли бы просто сделать что-то вроде этого:

SELECT *
FROM foo
WHERE (@param = 0 AND MyColumn IS NULL)
OR (@param = 1 AND MyColumn IS NOT NULL)
OR (@param = 2)

Нечто подобное.

10 голосов
/ 01 мая 2009

Вот как это можно сделать, используя CASE:

DECLARE @myParam INT;
SET @myParam = 1;

SELECT * 
  FROM MyTable
 WHERE 'T' = CASE @myParam
             WHEN 1 THEN 
                CASE WHEN MyColumn IS NULL THEN 'T' END
             WHEN 2 THEN
                CASE WHEN MyColumn IS NOT NULL THEN 'T' END
             WHEN 3 THEN 'T' END;
10 голосов
/ 01 мая 2009
WHERE MyColumn = COALESCE(@value,MyColumn) 
  • Если @value равно NULL, он будет сравнивать MyColumn с собой, игнорируя @value = no where пункт.

  • IF @value имеет значение (NOT NULL), которое будет сравниваться MyColumn с @value.

Ссылка: COALESCE (Transact-SQL) .

5 голосов
/ 18 июля 2013

Другой способ CASE:

SELECT *  
FROM MyTable
WHERE 1 = CASE WHEN @myParm = value1 AND MyColumn IS NULL     THEN 1 
               WHEN @myParm = value2 AND MyColumn IS NOT NULL THEN 1 
               WHEN @myParm = value3                          THEN 1 
          END
0 голосов
/ 17 августа 2017

У меня был успех с этим решением. Это почти как у Патрика, с небольшим поворотом. Вы можете использовать эти выражения по отдельности или в последовательности. Если параметр пуст, он будет проигнорирован, и будут отображены все значения для столбца, в котором выполняется поиск, включая NULLS.

SELECT * FROM MyTable
WHERE 
    --check to see if @param1 exists, if @param1 is blank, return all
    --records excluding filters below
(Col1 LIKE '%' + @param1 + '%' OR @param1 = '')
AND
    --where you want to search multiple columns using the same parameter
    --enclose the first 'OR' expression in braces and enclose the entire 
    --expression 
((Col2 LIKE '%' + @searchString + '%' OR Col3 LIKE '%' + @searchString + '%') OR @searchString = '')
AND
    --if your search requires a date you could do the following
(Cast(DateCol AS DATE) BETWEEN CAST(@dateParam AS Date) AND CAST(GETDATE() AS DATE) OR @dateParam = '')
...