2010-11-23 83 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 

我認爲這是更優雅且不易出錯,但它是一個愛好問題。這可能會更難閱讀。