操作与时间流逝
让我说明情况操作与时间流逝
我有两个表:
-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
我需要验证所有的场景,如果故障开始第一并完成休息等...
我的问题是,存在一个自动做到这一点的功能?
还是更优雅的解决方案?
我正在做一些类似的时间输入工具,需要检测输入的时间之间的重叠。如果你真正需要的是“我有一个错误,在错误期间会有一次休息,给我他们同时发生的时间”,那么你的功能就是正确的。
当我做了我的工作之后,我发现在视觉上探索测试用例比真值表好,并且都比散文或代码更好。
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
如果我必须做你说的话,这可能是我想要的。
这就是说,在分析你的问题时,我想知道你是否不必担心每个错误会有多次中断,如果你正在尝试为结果集中的所有错误执行此操作, “每个设备每周的时间”等等。如果是这样,你需要另一种方法。但那是另一个答案。
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
我认为这是更优雅且不易出错,但它是一个爱好问题。这可能会更难阅读。
哦,这种方法是如此的优雅。只有你犯了一个错误:“SET @biggestStart = CASE WHEN @FaultStartDate> @BreakStartDate THEN @FaultStartDate ELSE @BreakEndDate END;”错误是在最后一个@BreakEndDate,它必须是@BreakStartDate – 2010-11-24 23:33:07