t-sql: переключение оператора BETWEEN в зависимости от значения строки - PullRequest
3 голосов
/ 19 августа 2011

Я упростил здесь мой пример, поэтому, извините, если он выглядит просто для того, что я пытаюсь решить.

Можно ли превратить BETWEEN в NOT BETWEENв зависимости от значения строки (я использовал здесь переменную для простоты), без дублирования оператораween?

Я понимаю использование операторов case и логической логики, чтобы помочь сделать static 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 .... где-то используется для вставки НЕ.


РЕДАКТИРОВАТЬ 2:

Пожалуйста, смотрите ниже некоторые псевдокод для того, что я пытаюсь достичь.Это псевдо, так как t-SQL не позволяет «вставлять» «НЕ» в код в операции, основанной на наборе, подобной этой (я пытаюсь избежать строчно-динамического 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'
) 

Ответы [ 3 ]

7 голосов
/ 19 августа 2011

Я думаю, тебе просто нужно больше паренов ...

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

Понял - так что-то вроде этого:

WHERE @is = CASE WHEN DOB BETWEEN '2011-08-18' AND '2012-08-18' THEN 1 ELSE 0 END
1 голос
/ 19 августа 2011

Надеюсь, это будет полезно.

    SELECT Name, DOB FROM @TestTable WHERE 
CASE WHEN @is = 1 THEN DOB ELSE '1900' END BETWEEN '2011-08-18' AND '2012-08-18'
0 голосов
/ 19 августа 2011

Просто используйте логику, чтобы объединить их в одно утверждение:

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

Это говорит о том, что «истина» обеих сторон должна быть одинаковой (либо ложной, либо оба истинной), что и является вашим кодомможет быть уменьшено до.

...