SQL: предложение IF в предложении WHERE - PullRequest
180 голосов
/ 18 сентября 2008

Можно ли использовать предложение IF в предложении WHERE в MS SQL?

Пример:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'

Ответы [ 12 ]

193 голосов
/ 18 сентября 2008

Используйте оператор CASE
ОБНОВЛЕНИЕ: Предыдущий синтаксис (как указано несколькими людьми) не работает. Вы можете использовать CASE следующим образом:

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

Или вы можете использовать оператор IF, например @ N. Дж. Рид указывает.

127 голосов
/ 18 сентября 2008

Вы должны быть в состоянии сделать это без каких-либо IF или CASE

 WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

В зависимости от разновидности SQL вам может понадобиться настроить приведение номера заказа к INT или VARCHAR в зависимости от того, поддерживаются ли неявные приведения.

Это очень распространенный метод в предложении WHERE. Если вы хотите применить некоторую логику «ЕСЛИ» в предложении WHERE, все, что вам нужно сделать, это добавить дополнительное условие с логическим И в раздел, где его нужно применить.

19 голосов
/ 22 января 2016

Вам вовсе не нужен оператор IF.

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')
13 голосов
/ 18 сентября 2008

Нет хорошего способа сделать это в SQL. Некоторые подходы, которые я видел:

1) Использовать CASE в сочетании с логическими операторами:

WHERE
    OrderNumber = CASE 
        WHEN (IsNumeric(@OrderNumber) = 1)
        THEN CONVERT(INT, @OrderNumber)
        ELSE -9999 -- Some numeric value that just cannot exist in the column
    END
    OR 
    FirstName LIKE CASE
        WHEN (IsNumeric(@OrderNumber) = 0)
        THEN '%' + @OrderNumber
        ELSE ''
    END

2) Используйте IF вне SELECT

IF (IsNumeric(@OrderNumber)) = 1
BEGIN
    SELECT * FROM Table
    WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
    SELECT * FROM Table
    WHERE OrderNumber LIKE '%' + @OrderNumber
END

3) Используя длинную строку, составьте свой оператор SQL условно, а затем используйте EXEC

Третий подход отвратителен, но это почти единственная мысль, которая работает, если у вас есть несколько таких переменных условий.

6 голосов
/ 18 сентября 2008

Используйте оператор CASE вместо IF.

4 голосов
/ 18 сентября 2008

Требуется оператор CASE

WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END
3 голосов
/ 01 декабря 2010

Я думаю, что где ... как / = ... case ... тогда ... может работать с логическими значениями. Я использую T-SQL.

Сценарий: допустим, вы хотите получить увлечения Person-30, если bool имеет значение false, и увлечения Person-42, если bool имеет значение true. (По некоторым данным, хобби-поиски составляют более 90% циклов бизнес-вычислений, поэтому платите внимательно).

CREATE PROCEDURE sp_Case
@bool   bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID = 
    case @bool 
        when 0 
            then 30
        when 1
            then 42
    end;
1 голос
/ 20 января 2011
WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) 
             AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%' 
                                              + @OrderNumber + '%')
0 голосов
/ 12 марта 2019

CASE Выписка лучше, чем IF всегда.

  WHERE  vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE  @FromDate END
    AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END 
0 голосов
/ 22 апреля 2013

Следующий пример выполняет запрос как часть логического выражения, а затем выполняет несколько другие блоки операторов на основе результата логического выражения. Каждый блок операторов начинается с BEGIN и заканчивается END.

USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
   SET @BikeCount = 
        (SELECT COUNT(*) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   SET @AvgWeight = 
        (SELECT AVG(Weight) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
   PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE 
BEGIN
SET @AvgWeight = 
        (SELECT AVG(Weight)
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%' );
   PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO

Использование вложенных операторов IF ... ELSE В следующем примере показано, как оператор IF… ELSE может быть вложен в другой. Установите для переменной @Number значения 5, 50 и 500 для проверки каждого оператора.

DECLARE @Number int
SET @Number = 50
IF @Number > 100
   PRINT 'The number is large.'
ELSE 
   BEGIN
      IF @Number < 10
      PRINT 'The number is small'
   ELSE
      PRINT 'The number is medium'
   END ;
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...