开发者

t-sql: Flipping a BETWEEN operator depending on row value

开发者 https://www.devze.com 2023-03-29 13:49 出处:网络
I\'ve simplified my example here massively, so please excuse it if it looks to simple for what I\'m trying to solve.

I've simplified my example here massively, so please excuse it if it looks to simple for what I'm trying to solve.

Is it possible to turn BETWEEN, into a NOT BETWEEN depending on a row value (i've开发者_StackOverflow社区 used a variable here for simplicity), without duplicating the between statement?

I understand the use of case statements and boolean logic to help make static sql more "dynamic", but I can't seem to figure out a way for operators like BETWEEN.

Perhaps using some clever bitwise operation?

I have some set based SQL in development that is becoming difficult to manage already, so I'm hoping to simplify it by avoiding duplication.

I'm trying to do it in a SET based way, avoiding UDF's if possible.

DECLARE @is int
set @is = 1

DECLARE @TestTable TABLE
(
    Name varchar(100),
    DOB datetime
)

INSERT INTO @TestTable(Name, DOB)
SELECT 'bob', '2011-08-18 10:10:10.100' UNION ALL
SELECT 'fred', '2014-08-18 10:10:10.100'


SELECT Name, DOB
FROM @TestTable
WHERE
    (@is = 1) AND (DOB BETWEEN '2011-08-18' AND '2012-08-18') 
    OR
    (@is = 0) AND (DOB NOT BETWEEN '2011-08-18' AND '2012-08-18')

So in the example above, if @is = 1, then bob is returned. If @is = 0, then fred is returned.


EDIT: To clarify, the above statement works fine, but I'm attempting to optimise it to avoid having to write 2 BETWEEN statements. I wish to flip the logic depending on the value of @is.... somewhere using is to put in the NOT.


EDIT 2:

Please see below for some pseudo code for what I'm trying to achieve. It's pseudo, as t-SQL doesn't allow "NOT" to be "injected" in the code in a set based operation like this (I'm trying to avoid stringy-dynamic sql).

SELECT Name, DOB
FROM @TestTable
WHERE
(
    DOB
        CASE @is
            WHEN 0
            THEN NOT ---pseudo code, this won't actually work, but gives an idea of what I'm trying to achieve.
        END
    BETWEEN '2011-08-18' AND '2012-08-18'
) 


I think you just need more parens...

WHERE
    (   (@is = 1) AND (DOB BETWEEN '2011-08-18' AND '2012-08-18')   )
    OR
    (   (@is = 0) AND (DOB NOT BETWEEN '2011-08-18' AND '2012-08-18')   )

EDIT

Got it -- so then something like this:

WHERE @is = CASE WHEN DOB BETWEEN '2011-08-18' AND '2012-08-18' THEN 1 ELSE 0 END


Hope this will be of helpful.

    SELECT Name, DOB FROM @TestTable WHERE 
CASE WHEN @is = 1 THEN DOB ELSE '1900' END BETWEEN '2011-08-18' AND '2012-08-18'


Just use logic to combine them into one statement:

(@is = 1) = (DOB BETWEEN '2011-08-18' AND '2012-08-18') 

This says that the "truth" of both sides must be the same (either both false or both true), which is what your code can be reduced down to.

0

精彩评论

暂无评论...
验证码 换一张
取 消