在SQL CASE的WHERE子句中使用BETWEEN

7

我有一个表单,用户可以从中拉取报告。 在表单中,他们可以选择开始日期和结束日期,或者将两个值都设置为null。如果他们选择了null,则返回所有effectivedate小于GETDATE()的记录。 CASE语句似乎不喜欢between,也不喜欢'<'操作符。

以下是我的脚本

SELECT * FROM tbReport
WHERE 
    EffectiveDate 
    CASE 
        WHEN (@StartDate IS NOT NULL AND @EndDate IS NOT NULL) 
        THEN BETWEEN (@StartDate AND @EndDate)          
         ELSE 
                  THEN < GETDATE()

    END
6个回答

9
您可以将其重写为不区分大小写的形式,例如:
SELECT  * 
FROM   tbReport
WHERE   (
            @StartDate is not null 
            and 
            @EndDate is not null
            and 
            EffectiveDate between @StartDate AND @EndDate
        )
        or
        (
            (
                @StartDate is null 
                or 
                @EndDate is null
            )
            and 
            EffectiveDate < getdate()
        )

谢谢,这个答案对我来说最有意义,并考虑了所有条件。 - MeltdownZA
它能够工作,但对于所需的功能来说是否有点复杂了?从可维护性的角度来看,这不会是我的首选。 - SecretDeveloper

2
假设这是SQL Server,您可以使用isnull来简化此操作:
select *
from tbReport
where EffectiveDate between isnull(@StartDate, '1 Jan 1990')
      and isnull(@EndDate, getdate())

不幸的是,这没有考虑到如果任一日期为空,则返回所有记录,其中effectivedate < GETDATE()。 - MeltdownZA
如果你把BETWEEN换成AND,那么当任一参数为空时就可以处理了。看看我的答案就知道我是什么意思。 - SecretDeveloper

2

像这样应该可以工作,但我还没有检查语法是否正确。

SELECT * FROM tbReport
WHERE EffectiveDate < IsNull(@EndDate,GetDate())
AND EffectiveDate > IsNull(@StartDate,'01/01/1979')

0

你在这里使用 CASE 的语法是完全错误的。请尝试使用以下语法:

SELECT * FROM tbReport
WHERE 
    (@StartDate is null and @EndDate is null and EffectiveDate < GetDate()) or 
    (@StartDate is not null and @EndDate is not null and 
     EffectiveDate >= @StartDate and EffectiveDate <= @EndDate)

虽然这是一个非常好的选择,但是你应该在第一个@startdate和@enddate之间加上or (@StartDate is null or @EndDate is null)并且EffectiveDate < GetDate(),否则您将会遗漏一些记录。 - Dumitrescu Bogdan

0

SQL语句书写不正确。Case将不会有条件地选择评估的代码。您可以将case视为一个值,因此必须在case和其他操作数之间放置运算符。

编写此代码的多种方法之一是:

where 
case when @StartDate IS NOT NULL AND @EndDate IS NOT NULL and EffectiveDate BETWEEN (@StartDate AND @EndDate)   then 1
case when (@StartDate IS NULL OR @EndDate IS NULL) and EffectiveDate <getdate() then 1
else 0 end = 1

如果您不想按照大小写来编写,您可以选择之前的其中一种解决方案,但它们都使用离散的开始日期。


0
WHERE 

(SR.RecCreateTS BETWEEN  ( CASE WHEN  @SubmittedBegining IS NOT NULL  THEN @SubmittedBegining ELSE SR.RecCreateTS END )
                            AND ( CASE WHEN  @SubmittedEnding IS NOT NULL   THEN @SubmittedEnding ELSE SR.RecCreateTS END )
                            )

你好!请格式化你的代码(使用Ctrl+K),并编辑你的回答以描述它如何解决问题。 - Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接