2013-11-21 51 views
0

我想写一个条件查询条件下面的表的日期,有时它需要很好的思考。具有多个日期条件的SQL查询

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<[email protected] OR @StartDtm IS NULL) AND (StopDtm>[email protected] OR StopDtm IS NULL)) 
    OR((StartDtm>[email protected] OR @StartDtm IS NULL) AND (StopDtm>[email protected] AND StartDtm<= @StopDtm OR StopDtm IS NULL OR @StopDtm IS NULL)) 
    OR((StartDtm>[email protected] OR @StartDtm IS NULL) AND (StopDtm<[email protected] 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)>[email protected]) 
    OR(StartDtm>[email protected] and ISNULL(StopDtm,@StopDtm)<[email protected]) 
    OR(StartDtm between @StartDtm AND @StopDtm and ISNULL(StopDtm,@StopDtm)>[email protected] ) 
    OR(StartDtm<[email protected] AND ISNULL(StopDtm,@StopDtm) between @StartDtm AND @StopDtm) 

建议如果任何逻辑上的错误/变更/改进。

回答

0

是否

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

为你工作?

+0

是。它应该工作。目的是获取任务列表。如果赋予StartDtm和StopDtm之间的日期范围,则OR之前的条件将工作,但如果表中的StopDtm为空,那么它只需要在StartDtm上运行,并且应该避免StopDtm条件检查。 –

0

试试这个

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)) 
+0

它不工作。检查它是否存在有问题的日期范围。为此,它应该提供所有记录,但是您的情况不会给出任何记录。 –

+0

@ChiragFanse我无法理解为什么对于给定的参数范围('2013-11-15',2013-11-21'),查询应该提供所有记录。 也许这是很好的描述你的业务领域,而不是你的数据库环境 –

+0

前四条记录没有StopDtm&因此被认为是无限期结束。因此,即使他们很少有StartDtm <'2013-11-15',它会因为StopDtm(这是无限的)总会是<'2013-11-21',这意味着这些任务的发生将落在给定范围内。对于剩余的3条记录,任务在15日后开始,但会在21日后结束。因此,在2013-11-15至2013-11-21的日历中,会发生这些任务。日期列显示任务从日期X开始,并将继续发生,直到日期y。如果任何事件发生在范围内,则应该导致o/p –