ti-enxame.com

Cláusula SQL: IF dentro da cláusula WHERE

É possível usar uma cláusula IF dentro de uma cláusula WHERE no MS SQL?

Exemplo:

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

Use uma instrução CASE
ATUALIZAÇÃO: A sintaxe anterior (como apontado por algumas pessoas) não funciona. Você pode usar CASE da seguinte forma:

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

Ou você pode usar uma instrução IF como @ N. J. Reed aponta.

193
bdukes

Você deve ser capaz de fazer isso sem qualquer IF ou CASE

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

Dependendo do sabor do SQL, você pode precisar Ajustar os lançamentos no número do pedido para um INT ou VARCHAR, dependendo se as conversões implícitas são suportadas.

Essa é uma técnica muito comum em uma cláusula WHERE. Se você quiser aplicar alguma lógica "IF" na cláusula WHERE, tudo o que você precisa fazer é adicionar a condição extra com um booleano AND à seção onde ela precisa ser aplicada.

128
njr101

Você não precisa de uma instrução IF.

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

Não há uma boa maneira de fazer isso no SQL. Algumas abordagens que tenho visto:

1) Use CASE combinado com operadores booleanos:

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) Use IF fora do SELECT

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

3) Usando uma string longa, componha sua instrução SQL condicionalmente e, em seguida, use EXEC

A terceira abordagem é horrível, mas é quase o único pensamento que funciona se você tiver um número de condições variáveis ​​como essa.

13
Euro Micelli

Use uma instrução CASE em vez de IF.

6
Joel Coehoorn

Você quer a instrução CASE

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

Eu acho que onde ... como/= ... caso ... então ... pode trabalhar com booleanos. Eu estou usando o T-SQL.

Cenário: Digamos que você queira obter os hobbies do Person-30 se bool for falso, e os hobbies de Person-42 se bool forem verdadeiros. (De acordo com alguns, as pesquisas de hobby abrangem mais de 90% dos ciclos de computação de negócios, portanto, pague atentamente.).

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;
3
William
 WHERE (IsNumeric (@OrderNumber) <> 1 ORNúmeroDaEncomenda = @OrderNumber) 
 AND (IsNumber (@OrderNumber) = 1 ORNúmero do Pedido COMO '%' 
 + @OrderNumber + '%') 
1
WhoIsNinja

O exemplo a seguir executa uma consulta como parte da expressão booleana e, em seguida, executa blocos de instrução ligeiramente diferentes com base no resultado da expressão booleana. Cada bloco de instrução começa com BEGIN e é concluído com 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

Usando instruções IF ... ELSE aninhadas O exemplo a seguir mostra como uma instrução IF… ELSE pode ser aninhada dentro de outra. Defina a variável @Number para 5, 50 e 500 para testar cada instrução.

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
0
hossein

CASE Statement é uma opção melhor que IF always.

  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
Majedur Rahaman