3

ここでの例は大幅に単純化されているため、解決しようとしていることが単純に見える場合はご容赦ください。

BETWEENbetween ステートメントを複製せずに、を行の値に依存するようにすることは可能ですかNOT BETWEEN(ここでは簡単にするために変数を使用しました)。

静的SQLをより「動的」にするのに役立つcaseステートメントとブール論理の使用を理解していますが、のような演算子の方法を理解できないようですBETWEEN

おそらく、巧妙なビット単位の操作を使用していますか?

すでに管理が難しくなっている開発中のセットベースの SQL があるため、重複を避けて単純化したいと考えています。

可能であればUDFを避けて、SETベースの方法でそれをやろうとしています。

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では、このようなセットベースの操作でコードに「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'
) 
4

3 に答える 3

7

もっと括弧が必要だと思います...

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
于 2011-08-19T15:40:41.683 に答える
1

これが役立つことを願っています。

    SELECT Name, DOB FROM @TestTable WHERE 
CASE WHEN @is = 1 THEN DOB ELSE '1900' END BETWEEN '2011-08-18' AND '2012-08-18'
于 2011-08-19T16:02:55.803 に答える
0

ロジックを使用してそれらを 1 つのステートメントに結合するだけです。

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

これは、両側の「真実」が同じでなければならないことを示しています (両方とも false または両方とも true)。これは、コードを縮小できるものです。

于 2011-08-19T15:44:39.063 に答える