Предложение SQL: IF в разделе WHERE

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

Пример:

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

Ответ 1

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

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

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

Ответ 2

Вы можете сделать это без 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. Если вы хотите применить некоторую логику "IF" в предложении WHERE, все, что вам нужно сделать, это добавить дополнительное условие с булевым И в раздел, где это необходимо применить.

Ответ 3

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

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')

Ответ 4

В 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

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

Ответ 5

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

Ответ 6

Вам нужен оператор CASE

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

Ответ 7

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

Сценарий: скажем, вы хотите получить хобби Person-30, если bool является ложным, а хобби Person-42, если bool истинно. (По мнению некоторых, хобби-поиски составляют более 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;

Ответ 8

WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) 
             AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%' 
                                              + @OrderNumber + '%')

Ответ 9

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

Ответ 10

CASE Statement - лучший вариант, чем 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 

Ответ 11

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

В случае строки Условие будет работать правильно.

Ответ 12

If @LstTransDt is Null
                begin
                    Set @OpenQty=0
                end
            else
                begin
                   Select   @OpenQty=IsNull(Sum(ClosingQty),0)  
                   From  ProductAndDepotWiseMonitoring  
                   Where   [email protected] And [email protected] And [email protected]      
                end 

Посмотрите, поможет ли это.

Ответ 13

USE AdventureWorks2012;
GO
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO