0

I am not a db admin by any means so if semantics look a bit bizarre, I apologize. In SQL Server, is it possible to use a variable for a comparison operator like so?

declare @compare = '>';
declare @limit = '5';

select agentId, sessionId, duration
from table_x
where duration @compare @limit

I do not want to write a ton of lines depending on what the variable could be, which is why I ask. Not to mention if I throw in another variable, that further makes the amount of lines even larger. Also, I like the fact that it's extensible, so in the event there was an additional operator, it would just process it anyway.

Thanks for the help!

2
  • 3
    Not in a regular query. You can do this using dynamic SQL. Commented Nov 2, 2015 at 19:03
  • You can also do it with 2 variables.. @UpperLimit and @LowerLimit. (this is assuming you're only looking at > and <). Just throwing it out there. Commented Nov 2, 2015 at 19:08

3 Answers 3

4

You can, actually, by invoking different operators via a guard expression:

DECLARE @comparison varchar(2) = '>'
DECLARE @limit int 5 = 123

SELECT
    Foo
FROM
    Table
WHERE
    ( @comparson = '>' AND Duration > @limit )
    OR
    ( @comparson = '<' AND Duration < @limit )
    OR
    ( @comparson = '=' AND Duration = @limit )
    OR
    ( @comparson = '<>' AND Duration <> @limit )

To generalize this, you can convert this into a UDF and use it in multiple places:

CREATE FUNCTION VariableComparison(@comparison AS varchar(2), @value as numeric, @operand as numeric) RETURNS bit AS
BEGIN

    RETURN ( @comparison = '>' AND @value > @operand )
    OR
    ( @comparison = '<' AND @value < @operand )
    OR
    ( @comparison = '=' AND @value = @operand )
    OR
    ( @comparison = '<>' AND @value <> @operand )

END

Used like so:

SELECT
    ...
WHERE
    dbo.VariableComparison( @comparison, Duration, @limit ) = 1
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response, I thought about doing it this way, but I also have a timeUnit variable (sec, min, hrs) which makes the guard expression pretty long. But it looks like I'll just have to go this route.
@BobbyT. How are you storing time values? If you're storing data in a normalized (single column) value then you can use fractional/decimal units as operands.
0

You can try doing this using dynamic sql, something like

declare @compare varchar(2) = '>';
declare @limit int = '5';

declare @dynamicQuery = nvarchar(max) = N'select agentId, sessionId, duration
from table_x
where duration' + @compare + @limit

EXEC(@dynamicQuery)

Comments

0

One way of getting varied comparisons for numbers is to use sign():

where sign(duration - limit) = (case when @compare = '=' then 0
                                     when @compare = '>' then 1
                                     when @compare = '<' then -1
                                end)

However, these types of operations in the WHERE clause are not recommended because they preclude the use of indexes. Also, this structure doesn't work for strings or dates, but it does work for numbers.

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.