【问题标题】:SQL Query with multiple conditions on date日期上具有多个条件的 SQL 查询
【发布时间】:2013-12-05 10:49:25
【问题描述】:

我想为下表的日期编写一个带有条件的查询,有时它需要很好的思考。

StartDtm                             StopDtm
2013-11-03 00:00:00.000               NULL
2013-11-05 08:00:00.000               NULL
2013-11-18 09:00:00.000               NULL
2013-11-18 08:00:00.000               NULL
2013-11-19 08:00:00.000              2013-11-26 07:59:00.000
2013-11-20 08:00:00.000              2013-11-27 07:59:00.000
2013-11-19 08:00:00.000              2013-12-19 07:59:00.000

表格显示任务开始日期和任务结束日期。开始日期永远不能为空。 最后一条记录显示该任务从 11 月 19 日开始,到 12 月 19 日结束。所以如果我通过了任何日期,它应该显示所有需要在通过的日期范围内的任何日期执行的任务。

条件如下:

1.任何日期或两个日期参数都可以为空。如果是这样,所有数据都应该来。

2.如果@StartDtm 为null 并且传递了@StopDtm,那么它应该只带入所有基于StopDtm 字段的数据,而不应该带入那些StartDtm 大于@StopDtm 的数据。 @StopDtm 参数也一样

3.如果 StopDtm 字段为空,它应该只带来基于 StartDtm 字段的所有数据

我尝试了几种方法,但都没有成功。我保持状态尽可能短。如果可能的话,请提供多个查询,几乎没有解释。

我的查询如下:

DECLARE @StartDtm datetime='2013-11-15'
DECLARE @StopDtm datetime='2013-11-21'

select * from #TempTbl
where  ((StartDtm<=@StartDtm OR @StartDtm IS NULL)  AND (StopDtm>=@StopDtm OR StopDtm IS NULL))
    OR((StartDtm>=@StartDtm OR @StartDtm IS NULL) AND (StopDtm>=@StopDtm AND StartDtm<= @StopDtm OR StopDtm IS NULL OR @StopDtm IS NULL))
    OR((StartDtm>=@StartDtm OR @StartDtm IS NULL) AND (StopDtm<=@StopDtm OR StopDtm IS NULL OR @StopDtm IS NULL))

提前谢谢.. StackOverflow 中已经提出了这个问题,但我在这里找不到如何迁移它。于是又在这里问。

创建了另一个看起来运行良好的查询:

DECLARE @StartDtm datetime='2013-11-20'
DECLARE @StopDtm datetime='2013-11-30'

IF(@StartDtm is null)
begin
    SET @StartDtm='1900-01-01'
end
IF(@StopDtm IS NULL)
begin
    SET @StopDtm='9999-12-31'
end

select * from #TempTbl
where (startDtm<= @StartDtm and ISNULL(StopDtm,@StopDtm)>=@StopDtm )
  OR(StartDtm>=@StartDtm and ISNULL(StopDtm,@StopDtm)<=@StopDtm )
  OR(StartDtm between @StartDtm AND @StopDtm and ISNULL(StopDtm,@StopDtm)>=@StopDtm  )
  OR(StartDtm<=@StartDtm AND ISNULL(StopDtm,@StopDtm) between @StartDtm AND  @StopDtm)

如果有任何逻辑错误/更改/改进,请提出建议。

【问题讨论】:

    标签: sql sql-server datetime


    【解决方案1】:

    WHERE (StartDtm <= @StopDtm AND @StopDtm >= @StartDtm) OR (StartDtm >= @StartDtm AND StopDtm IS NULL) 
    

    为你工作?

    【讨论】:

    • 是的。它应该工作。目的是获取任务列表。如果给定日期范围在 StartDtm 和 StopDtm 之间,则 OR 之前的条件将起作用,但如果 StopDtm 在表中为空,在这种情况下,它只需要对 StartDtm 进行操作,并且应避免 StopDtm 条件检查。
    【解决方案2】:

    试试这个

    WHERE (@StartDtm IS NULL OR StartDtm = @StartDtm)
      AND (@StopDtm IS NULL OR StopDtm = @StopDtm)
      OR ( ISNULL(@StartDtm,@StopDtm) = NULL OR (StartDtm> @StartDtm AND StopDtm < @StopDtm ) )
    

    【讨论】:

    • 它不工作。检查它以获取有问题的日期范围。为此,它应该提供所有记录,但您的条件没有提供任何记录。
    • @ChiragFanse 我不明白为什么对于给定的参数范围('2013-11-15',2013-11-21'),查询应该给出所有记录。也许最好描述您的业务领域而不是您的数据库环境
    • 前四个记录没有 StopDtm,因此被认为在无限日期结束。因此,即使其中很少有 StartDtm
    猜你喜欢
    • 2017-02-24
    • 1970-01-01
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多