我在这里大大简化了我的示例,所以如果它看起来对我要解决的问题来说很简单,请原谅。
是否可以根据行值将 BETWEEN
转换为 NOT BETWEEN
(为简单起见,我在这里使用了变量),而无需重复 between 语句?
我了解使用 case 语句和 bool 逻辑来帮助使静态 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')
所以在上面的例子中,如果@is = 1,则返回 bob。 如果@is = 0,则返回 fred。
编辑: 澄清一下,上述语句工作正常,但我正在尝试对其进行优化以避免编写 2 个 BETWEEN 语句。我希望根据 @is.... 的值翻转逻辑。在某处使用 is 放入 NOT。
编辑2:
请参阅下面的一些伪代码,了解我想要实现的目标。这是伪的,因为 t-SQL 不允许在这样的基于集合的操作中在代码中“注入(inject)”“NOT”(我试图避免字符串动态 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'
)
最佳答案
我认为你只是需要更多的括号...
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
关于sql - t-sql : Flipping a BETWEEN operator depending on row value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7123929/