0

I am having trouble using CASE when attempting to return the appropriate results based on whether a certain value is passed.

For example I would like to run a query if the suburb is passed

WHEN @suburb <> '' THEN
@suburb 
END
= [Suburb]
AND 
[City] = @city

However how do I only run the query so that when no suburb is passed it only uses the city?

Should I rather write the query as follows?

WHERE
(
    [Suburb] = @suburb
    AND
    [City] = @city
)
OR
(
    [City] = @city
)
Aaron Bertrand
  • 272,866
  • 37
  • 466
  • 490
PeanutsMonkey
  • 6,919
  • 23
  • 73
  • 103

4 Answers4

1

You don't really need CASE:

WHERE (suburb = @suburb OR @suburb = '' OR @suburb IS NULL) AND city = @city
John Pick
  • 5,562
  • 31
  • 31
  • That worked like a charm. A question though as I a newbie to SQL. I am guessing that the OR statement is only fulfilled if the first condition fails e.g. if `suburb = @suburb` does not have a value only the does it then proceed to process `@suburb = ''`. Is thar right? – PeanutsMonkey Feb 21 '12 at 21:32
  • 1
    No, SQL does not short-circuit. All expressions are evaluated. – John Pick Feb 21 '12 at 21:36
  • The article at http://weblogs.sqlteam.com/jeffs/archive/2003/11/14/513.aspx seems to suggest it does unless I have misunderstood. If all conditions are evaluated, is it posisble that all those conditions can be met? – PeanutsMonkey Feb 21 '12 at 21:48
  • I'm not sure where that article implies that short-circuiting is guaranteed, but it is not, not even inside CASE. Please read this entire question and its answers: http://dba.stackexchange.com/questions/12941/does-sql-server-read-all-of-a-coalesce-function-even-if-the-first-argument-is-no/12945#12945 – Aaron Bertrand Feb 21 '12 at 21:59
  • I stand corrected. SQL does not *reliably* short-circuit. Good discussion here: http://stackoverflow.com/questions/789231/is-the-sql-where-clause-short-circuit-evaluated – John Pick Feb 21 '12 at 22:00
  • @Aaron Bertrand & John Pick - Thanks guys. – PeanutsMonkey Feb 21 '12 at 22:26
  • @John Pick I would even state it the other way around, sort of. *SQL Server may short circuit, but don't rely on it.* – Aaron Bertrand Feb 21 '12 at 22:36
  • @John Pick - When do you use `CASE`? – PeanutsMonkey Feb 23 '12 at 19:35
  • @PeanutsMonkey MSDN has some good examples: http://msdn.microsoft.com/en-us/library/ms181765.aspx – John Pick Feb 23 '12 at 19:48
1

Since you're using SQL Server 2008, you'll want to use the OPTION (RECOMPILE) hint here to avoid caching an inappropriate plan. See Catch-all queries for more details.

...
WHERE ((@suburb = '') OR (@suburb <> '' AND [Suburb] = @suburb))
    AND [City] = @city
OPTION (RECOMPILE)
Joe Stefanelli
  • 132,803
  • 19
  • 237
  • 235
1

There are a few alternative ways to achieve, you can try one of these..

WHERE [City] = @city
AND ([Suburb] = @suburb  OR '' = '')
Thit Lwin Oo
  • 3,388
  • 3
  • 20
  • 23
0
SELECT FirstName, LastName, TelephoneNumber, "When to Contact" = 
 CASE
      WHEN TelephoneSpecialInstructions IS NULL THEN 'Any time'
      ELSE TelephoneSpecialInstructions
 END

FROM Person.vAdditionalContactInfo;