t-sql:根据行值翻转BETWEEN运算符

Ale*_*ith 3 sql t-sql between

我在这里大量简化了我的例子,所以请原谅它,如果它看起来很简单我想要解决的问题.

是否可以BETWEEN转换为NOT BETWEEN依赖于行的值(为了简单起见,我在这里使用了一个变量),而不重复之间的语句?

我理解使用case语句和布尔逻辑来帮助使静态sql更"动态",但我似乎无法为运营商找到一种方法BETWEEN.

也许使用一些聪明的按位操作?

我在开发中有一些基于集合的SQL已经变得难以管理,所以我希望通过避免重复来简化它.

我试图以基于SET的方式进行,如果可能的话,避免使用UDF.

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')
Run Code Online (Sandbox Code Playgroud)

所以在上面的例子中,如果@is = 1,则返回bob.如果@is = 0,则返回fred.


编辑:为了澄清,上述声明工作正常,但我正在尝试优化它,以避免编写2个BETWEEN语句.我希望根据@is的值来翻转逻辑....某处使用is来放入NOT.


编辑2:

请参阅下面的一些伪代码,了解我正在努力实现的目标.它是伪的,因为t-SQL不允许在这样的基于集合的操作中将"NOT""注入"代码中(我试图避免使用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'
) 
Run Code Online (Sandbox Code Playgroud)

Cha*_*ins 7

我想你只需要更多的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')   )
Run Code Online (Sandbox Code Playgroud)

编辑

得到它 - 所以这样的事情:

WHERE @is = CASE WHEN DOB BETWEEN '2011-08-18' AND '2012-08-18' THEN 1 ELSE 0 END
Run Code Online (Sandbox Code Playgroud)