2010-11-23 86 views
0

让我说明情况操作与时间流逝

我有两个表:

-One是存储设备故障,用自己的开始日期和结束日期。

- 其他来存储休息时间,每个休息时间都有一个开始日期和结束日期。

例如,故障从9:10开始并在9:16结束。休息时间从9点14分开始,到9点18分结束,故障时间为4分钟,因故障而中断2分钟的故障不算。我需要得到“2分钟”的价值包括它在一份报告中

来计算的话,我使用的是标量值函数:

DECLARE @Time int; 

SET @Time = 0; 

IF (@BreakStartDate > @FaultStartDate) AND (@BreakEndDate < @FaultEndDate) 
    SET @Time = DATEDIFF(SECOND, @BreakStartDate, @BreakEndDate); 

ELSE IF (@FaultStartDate > @BreakStartDate) AND (@FaultEndDate < @BreakEndDate) 
    SET @Time = DATEDIFF(SECOND, @FaultStartDate, @FaultEndDate); 

ELSE IF (@FaultStartDate < @BreakStartDate) AND ((@FaultEndDate > @BreakStartDate) AND (@FaultEndDate < @BreakEndDate)) 
    SET @Time = DATEDIFF(SECOND, @BreakStartDate, @FaultEndDate); 

ELSE IF (@FaultEndDate > @BreakEndDate) AND ((@FaultStartDate > @BreakStartDate) AND (@FaultStartDate < @BreakEndDate)) 
    SET @Time = DATEDIFF(SECOND, @FaultStartDate, @BreakEndDate); 

RETURN @Time 

我需要验证所有的场景,如果故障开始第一并完成休息等...

我的问题是,存在一个自动做到这一点的功能?

还是更优雅的解决方案?

回答

0

我正在做一些类似的时间输入工具,需要检测输入的时间之间的重叠。如果你真正需要的是“我有一个错误,在错误期间会有一次休息,给我他们同时发生的时间”,那么你的功能就是正确的。

当我做了我的工作之后,我发现在视觉上探索测试用例比真值表好,并且都比散文或代码更好。

Case 1:       Case 2: 
Fault: |-------|     Fault: |----------| 
Break:    |-------|  Break:  |----------| 

Case 3:       Case 4: 
Fault:  |----------|   Fault: |----------| 
Break: |----------|    Break: |------| 

...等等。

至于优雅这样做,我想指出的是,如果是两个失误之间的任何重叠,您总是拉闸想要更大的起始日期。像这样:

Start Dates: 
Fault: |----  ... |---- ...  |---- 
Break:  |---- ... |---- ... |---- 
Verdict: break  either  fault 

...和类似的最小结束日期。因为我们感兴趣的区域是两个都已经开始并且都没有完成。所以你的逻辑可以变成:

DECLARE @Time int, @biggestStart datetime, @smallestEnd datetime; 
SET @Time = 0; 

IF (@BreakStartDate < @FaultEndDate) AND (@BreakEndDate > @FaultStartDate) 
BEGIN 
    -- We have overlap. 
    -- Poor man's Math.Max and Math.Min: 
    SET @biggestStart = CASE WHEN @FaultStartDate > @BreakStartDate THEN @FaultStartDate ELSE @BreakEndDate END; 
    SET @smallestEnd = CASE WHEN @FaultEndDate < @BreakEndDate THEN @FaultEndDate ELSE @BreakEndDate END; 

    SET @Time = DATEDIFF(SECOND, @biggestStart, @smallestEnd); 
END 
RETURN @Time 

如果我必须做你说的话,这可能是我想要的。

这就是说,在分析你的问题时,我想知道你是否不必担心每个错误会有多次中断,如果你正在尝试为结果集中的所有错误执行此操作, “每个设备每周的时间”等等。如果是这样,你需要另一种方法。但那是另一个答案。

+0

哦,这种方法是如此的优雅。只有你犯了一个错误:“SET @biggestStart = CASE WHEN @FaultStartDate> @BreakStartDate THEN @FaultStartDate ELSE @BreakEndDate END;”错误是在最后一个@BreakEndDate,它必须是@BreakStartDate – 2010-11-24 23:33:07

0

AFAIK没有内置的功能。但是,如果将所有日期秒,因为一些随机的开始日期,我想你可以计算出故障的时间(以伪代码):

max(0; b1 - f1) - max(0; b2 - f2) 

其中B1,F1,B2和F2群体中给出下面,我已经把SQL代码来计算上述表达式(未经测试):

DECLARE @startDate DATETIME 
SET @startDate = '2010-01-01' -- Some date that must be smaller than all fault dates and break dates 

DECLARE @breakStartDate DATETIME 
DECLARE @breakEndDate DATETIME 
DECLARE @faultStartDate DATETIME 
DECLARE @faultEndDate DATETIME 

DECLARE @b1 INT 
DECLARE @b2 INT 
DECLARE @f1 INT 
DECLARE @f2 INT 

-- Set values for break and fault dates here 
SET @breakStartDate = .... 
SET @breakEndDate = .... 
SET @faultStartDate = .... 
SET @faultEndDate = .... 

SET @b1 = DATEDIFF(SECOND, @startDate, @breakStartDate) 
SET @b2 = DATEDIFF(SECOND, @startDate, @breakEndDate) 
SET @f1 = DATEDIFF(SECOND, @startDate, @faultStartDate) 
SET @f2 = DATEDIFF(SECOND, @startDate, @faultEndDate) 

DECLARE @time INT 

SET @time = 
CASE 
    WHEN @b1 - @f1 < 0 THEN 0 
    ELSE @b1 - @f1 
END 
+ 
CASE 
    WHEN @b2 - @f2 < 0 THEN 0 
    ELSE @b2 - @f2 
END 

SELECT @time 

我认为这是更优雅且不易出错,但它是一个爱好问题。这可能会更难阅读。