这里我的示例进行了大量简化,如果它看起来过于简单,请多多包涵,因为我想要解决的问题并不简单。
是否有可能根据行值(我在这里使用一个变量来简化)将BETWEEN
转换为NOT BETWEEN
,而无需复制between语句?
我知道可以使用case语句和布尔逻辑来帮助使静态SQL更加“动态”,但似乎对于像BETWEEN
这样的运算符,我无法找到一种方法。
也许可以使用一些巧妙的位操作?
我正在开发一些基于集合的SQL,已经变得难以管理,所以我希望通过避免重复来简化它。
我尝试以基于集合的方式进行操作,如果可能的话,避免使用UDFs。
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不允许在类似于这样的基于集合的操作中“注入”代码中的“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'
)
@is
是一个整数,因此它将与1和0一起使用,就像它是一个位一样。但是,如果您对@is
的值不是1和0(比如“是”或“否”),那么您只需要将这些值替换为CASE语句中的1和0即可。 - Chains