views:

63932

answers:

5

Is it possible to use an IF clause within a WHERE clause in MS SQL?

Example:

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

Use a CASE statement instead of IF.

Joel Coehoorn
+20  A: 

Use a CASE statement
UPDATE: The previous syntax (as pointed out by a few people) doesn't work. You can use CASE as follows:

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

Or you can use an IF statement like @N. J. Reed points out.

bdukes
Sorry. It's easy to forget that CASE doesn't work like that. CASE can only be used to pick values selectively, not to apply boolean logic. In SQL Server, booleans are not values that can be operated on. That example doesn't pass syntax check.
Euro Micelli
Thanks, Euro, I've adjusted my answer.
bdukes
[Note after the UPDATE by author]: That should work, but you should TRIM() both sides to make sure that a match is found. I have a gut feeling that there rare still edge cases that fail to match.
Euro Micelli
+1  A: 

You want the CASE statement

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

You should be able to do this without any IF or CASE

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

Depending on the flavour of SQL you may need to tweak the casts on the order number to an INT or VARCHAR depending on whether implicit casts are supported.

This is a very common technique in a WHERE clause. If you want to apply some "IF" logic in the WHERE clause all you need to do is add the extra condition with an boolean AND to the section where it needs to be applied.

njreed.myopenid.com
Very interesting. I never thought of it this way.
Bryan Roth
I'd imagine you take a bit of a performance hit over the CASE solution, though, since all of those conditions get evaluated, no?
Kevin Fairchild
Perfect - solved a long-standing problem for me; thanks for the pointer!
cori
I always forget that in SQL one can replace conditional statements with boolean logic like that. Thanks for the reminder, it's a very useful technique!
CodexArcanum
+2  A: 

There isn't a good way to do this in SQL. Some approaches I have seen:

1) Use CASE combined with boolean operators:

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's outside the SELECT

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

3) Using a long string, compose your SQL statement conditionally, and then use EXEC

The 3rd approach is hideous, but it's almost the only think that works if you have a number of variable conditions like that.

Euro Micelli