19

Hi I have query as follows:

    SELECT  route_id [ROUTE_ID]
    FROM route_master(NOLOCK)
    WHERE  route_ou = 2
    AND   route_query = @l_s_query
    AND   lang_id  = 1

Here, the " AND route_query = @l_s_query" condition in WHERE clause should be added only when @l_s_query is non empty. I donot want to write IF ELSE condition for @l_s_query. Is there any way to handle in WHERE clause itself directly.Thanks.

5
  • 4
    Perhaps ... AND (route_query = @l_s_query OR @l_s_query IS NULL) ...? Commented Aug 8, 2016 at 11:40
  • 4
    add this AND (@l_s_query IS NULL OR route_query = @l_s_query) Commented Aug 8, 2016 at 11:42
  • Possible duplicate of use optional parameter in WHERE clause Commented Aug 8, 2016 at 11:50
  • The question in the title "is not null" disagrees with the question in the header "is non empty" (since we call zero-length strings "empty"). This is why you've got two different answers, from sagi and Tamas. Commented Aug 8, 2016 at 13:13
  • I've previously used a CASE statement in queries like this, with the value being the same in a false case eg. ... AND route_query = (CASE WHEN @l_s_query is not null THEN @l_s_query ELSE route_query END) Commented Aug 8, 2016 at 13:21

5 Answers 5

28

You can translate your requirement into :

SELECT  route_id [ROUTE_ID]
FROM route_master(NOLOCK)
WHERE  route_ou = 2
AND   (@l_s_query is null OR route_query = @l_s_query)
AND   lang_id  = 1
OPTION (RECOMPILE)

The OPTION (RECOMPILE) is optional but can give better execution plans at the expense of extra compilation time as discussed in the canonical article on the topic Dynamic Search Conditions in T‑SQL

Or with COALESCE() to avoid the OR :

WHERE  route_ou = 2
AND   COALESCE(@l_s_query,route_query) = route_query 
AND   lang_id  = 1

Note: As @jarlh said, if route_query is nullable, this may cause some issues becuase of null comparison, so you may want to use the first query.

Another option of this is two separate queries using UNION ALL , one for each condition -

SELECT .. FROM .. 
WHERE @l_s_query IS NULL
UNION ALL
SELECT .. FROM .. 
WHERE @l_s_query = route_query

On terms of performance,only the last one will use the index, I believe the first one will be the fastest, but it may change depanding on the indexes, sizes of the tables ETC..

Sign up to request clarification or add additional context in comments.

4 Comments

Second query is a bit different when it comes to NULL values in route_query.
@jarlh Yea.. I've added a comment about this:)
what about performance implications? does this kind of expression not prevent index use, or are recent versions of mssql smart enough to account for that? I remember it was sometimes necessary to write two copies of such SELECTs, one with the parameter in the WHERE clause and one without, wrapped in an IF ... ELSE ... END
COALESCE(@l_s_query,route_query) = route_query , just found out first hand, this can cause problem if the value is null and the search parameter is null, null = null does not evaluate to true it seems.
4

the " AND route_query = @l_s_query" condition in WHERE clause should be added only when @l_s_query is non empty.

    WHERE  route_ou = 2
    AND   (  (@l_s_query IS NOT NULL AND route_query = @l_s_query ) OR
              @l_s_query IS NULL ) 
    AND   lang_id  = 1

Comments

2

Here is a better way to handle: using LEN(ISNULL)... OR:

AND (LEN(ISNULL(@l_s_query,'')) = 0 OR route_query = @l_s_query)

Comments

1

You can emulate if-else with an OR:

AND ((0 = len(@l_s_query) OR @l_s_query IS NULL OR route_query = @l_s_query)

Explanation:

  • AND (...) - the parentheses is required to apply the non-empty check only for this predicate
  • 0 < len(@l_s_query) - is a way to determine non-emptiness for varchar-s.

4 Comments

Your query will return zero results if@l_s_query is NULL or empty.
Indeed, OR is the right fallback-operator. Fixed the code accordingly.
Your syntax is off. You are missing an operator, I think. IS EMPTY doesn't seem to exist, though. And if @l_s_query is non-empty, it isn't checked against route_query.
Rght, fixed them too. If @l_s_query is checked against route_query if and only if it isn't empty or null.
0
SELECT  route_id [ROUTE_ID]
FROM route_master(NOLOCK)
WHERE  route_ou = 2
AND   (route_query = @l_s_query AND @l_s_query IS NOT NULL)
AND   lang_id  = 1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.