过滤SQL行

时间:2010-02-02 18:13:55

标签: sql sql-server-2005 tsql

表架构

ID     Activate_Date                InActivate_Date
1      2009-12-18 10:25:19.470  2010-01-13 08:32:30.130
2      2009-12-18 10:25:19.470  2010-01-13 08:32:30.253
3      2009-12-18 10:25:19.470  2010-01-13 08:32:30.363
4      2009-12-18 10:25:19.470  2010-01-13 08:32:30.583
5      2009-12-18 10:25:19.470  2010-01-13 08:32:30.473
6      2010-01-13 14:46:53.880  2010-01-13 14:50:45.443
7      2010-01-13 08:32:30.600  2010-01-13 14:46:23.833
8      2010-01-13 08:32:30.600  2010-01-13 14:46:23.833
9      2010-01-13 08:32:30.600  2010-01-13 14:46:23.833
10     2010-01-13 08:32:30.600  2010-01-13 14:46:23.833
11     2010-01-13 14:46:53.880  2010-01-13 14:50:45.443
12     2010-01-13 14:44:56.397  2010-01-13 14:46:23.833
13     2010-01-13 12:42:59.113  2010-01-13 14:46:23.833
14     2010-01-13 12:42:59.113  2010-01-13 14:46:23.833
15     2010-01-13 12:42:59.113  2010-01-13 14:46:23.833
16     2010-01-13 12:42:59.113  2010-01-13 14:46:23.833

输入参数:

Declare @StartDate DateTime
Declare @EndDate DateTime

Declare @FirstShiftStartTime varchar(8)
Declare @FirstShiftEndTime varchar(8)

Set @StartDate = '1/01/2010'
Set @EndDate = '1/03/2010'

SET @FirstShiftStartTime = '15:00:00'
SET @FirstShiftEndTime = '17:00:00'

输出:

输出应该是所有行,以便每天以移位的形式应用时间过滤器。因此,如果我们使用这些参数,那么输出应该是从ID 1到5的前5行。

因此输出过滤器应该应用为:

1/01/2010 from 15:00:00 to 17:00:00
2/02/2010 from 15:00:00 to 17:00:00
3/03/2010 from 15:00:00 to 17:00:00

我希望自己清楚明白:

我尝试使用:

((DatePart(Table.Activate_Date) <= @StartDate AND DatePart(Table.INActivate_Date) > @StartDate) OR
     (DatePart(Table.Activate_Date) >= @StartDate AND DatePart(Table.InActivate_Date) < @EndDate)
    )

AND ((TimePart(Table.Activate_Date) >=@FirstShiftStartTime ) AND (TimePart(Table.INActivate_Date) < @FirstShiftEndTime))

但如果激活日期和取消激活日期跨越多天,则无效。

我能找到的另一种方法是创建一个每天循环的临时表,然后用过滤器填充临时表,然后应用上面的方法。

我希望应该有一些简单的东西,然后我在思考。

任何帮助都将受到高度赞赏。

2 个答案:

答案 0 :(得分:0)

我认为你不能分别考虑日期和时间。如果您想知道02/02/2010中1500和1700之间的活动状态,并且该行的活动日期为01/01,非活动日期为03/03,那么它在02 /的整天都处于活动状态02,因此DB中的开始/结束时间不相关。

如果活动或非活动日期出现在相关日期(02/02)然后,您需要考虑时间。

我想你想要这样的伪代码:

   (ActivateDate < @StartDate OR ( 
        ActivateDate = @StartDate And ActivateTime <= @ShiftStartTime )
    )
and (InActivateDate > @EndDate OR ( 
        InActivateDate = @EndDate And InActivateTime >= @ShiftEndTime )
    )

答案 1 :(得分:0)

最后,我创建了一个CTE,其中包含输入日期范围内每天的DateTime过滤器,然后将CTE与表连接并应用distinct以获得结果。

更新:对于简单的日期范围检查,请使用:

dr1.EndDate&gt; = dr2.StartDate和dr1.StartDate&lt; = dr2.EndDate