t-sql:根据行值在运算符之间翻转

t-sql:根据行值在运算符之间翻转,sql,tsql,between,Sql,Tsql,Between,我已经在这里大量简化了我的示例,所以如果我试图解决的问题看起来很简单,请原谅 是否可以根据行值将BETWEEN转换为NOT BETWEEN(为了简单起见,我在这里使用了一个变量),而不复制BETWEEN语句 我了解如何使用case语句和布尔逻辑来帮助静态sql变得更“动态”,但我似乎无法为等操作符找到一种方法 也许使用一些聪明的位运算 我有一些基于集合的SQL正在开发中,现在已经很难管理了,所以我希望通过避免重复来简化它 我试图以一种基于集合的方式来做这件事,如果可能的话,尽量避免UDF DEC

我已经在这里大量简化了我的示例,所以如果我试图解决的问题看起来很简单,请原谅

是否可以根据行值将
BETWEEN
转换为
NOT BETWEEN
(为了简单起见,我在这里使用了一个变量),而不复制BETWEEN语句

我了解如何使用case语句和布尔逻辑来帮助静态sql变得更“动态”,但我似乎无法为
等操作符找到一种方法

也许使用一些聪明的位运算

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

我试图以一种基于集合的方式来做这件事,如果可能的话,尽量避免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')
因此,在上面的示例中,如果@is=1,则返回bob。 如果@is=0,则返回fred


编辑: 澄清一下,上面的语句很好用,但我试图优化它,以避免在语句之间写两个。我希望根据@is…的值来翻转逻辑。。。。某个地方使用的是放在NOT中


编辑2:

请参阅下面的一些伪代码,了解我试图实现的目标。它是伪的,因为t-SQL不允许像这样在基于集合的操作中“注入”代码中的“NOT”(我试图避免严格的动态SQL)


我想你只是需要更多的帕伦斯

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')   )
编辑

明白了,然后像这样:

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

只需使用逻辑将它们组合成一条语句:

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

这意味着双方的“真相”必须相同(要么都是假的,要么都是真的),这就是您的代码可以简化为的内容。

希望这会有所帮助

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

对不起,库鲁,我想我的问题不是很清楚。我问题中的SQL运行良好。但我正试图优化它,这样我就不需要在语句之间写2个,而是希望根据@isDude的值自动将中间转换为非中间!这是一些热门的sql,+1来自我!非常优雅的解决方案。我只是从一个稍微不同的角度读了一个类似的答案,并试图让我的头脑清醒过来。你的修正案来得正是时候,解释得很好。在某些情况下,我是否需要对其进行一些调整,或者它是否应该始终为我处理这些问题?如果有帮助,我将非常高兴。:-)至于位转换,这取决于您的变量。由于
@is
是一个int,它将与1和0一起工作,如果它是一个bit。但是,如果您的
@is
的值不是1和0(如“是”或“否”),那么您只需要在CASE语句中将这些值细分为1和0。感谢您提供的信息,事实上,我的输入错误@is意味着有点小。但是听起来好像我不需要类型转换,回答得很好,谢谢。这个解决方案完全无法组织(不能使用索引)。TSQL不允许您比较布尔语句的结果。你会认为它会起作用,但令人惊讶的是,这是无效的…有趣的建议波西米亚谢谢。然而,我也在试图返回相反的结果。因此,如果@is=0,仍然返回一个结果。我甚至不确定我要做的是否可以用sql来表示:-)很有趣,谢谢teenboy。库鲁提供了一个很好的解决方案。但是谢谢你的努力,你的看起来不错,我不能让它工作,但我喜欢语法的想法+从我这里得到1。
    SELECT Name, DOB FROM @TestTable WHERE 
CASE WHEN @is = 1 THEN DOB ELSE '1900' END BETWEEN '2011-08-18' AND '2012-08-18'