2012-09-05 162 views
3

我有一個SQL Server數據庫中的數據集,我需要計算一臺機器的正常運行時間。我使用兩個變量來確定正常運行時間或停機時間。這兩個變量是machine_ONfailure(s)machine_ON只是數據庫中的一個變量,failure可以是64個不同的失敗,但全部表示爲fx_xSQL Server查詢buildup

這些變量的狀態信息被存儲在數據庫如下:

timestamp     failurebitNr timestampOutOfAlarm 
2012-01-17 10:38:58.000  f1_14   2012-01-17 10:39:05.000 

含義:故障f1_14是活躍從2012-01-17 10:38:58.000直到2012-01-17 10:39:05.000

另外,machine_ON狀態保存在同一個表上同樣,只有failurebitNr具有不同的值[t2_13]。

所以要確定正常運行時間,我需要得到timestamptimestampOutOfAlarm之間的timediff,其中failurebutNr = 't2_13'減去任何故障時間。

因此,例如,我的那些行在我的數據庫:

Click for image of table representation

這應該給瞭如下圖示:

Graphical representation of the dataser

綠色是正常運行時間,紅色的停機時間。

我習慣於使用PHP,並使用while循環和文件的一些數組和其他腳本。但現在我需要在SQL Server數據庫中以查詢方式執行此操作...

那麼,如何計算正常運行時間(綠色)和停機時間(紅色)?

UPDATE

我試圖讓在幾秒鐘的時間,機器開啓。我用這個查詢:

<!-- language: lang-sql --> 
DECLARE @startDate datetime 
DECLARE @endDate datetime 
DECLARE @projectNr int 
DECLARE @MachineNr nvarchar(10) 

SET @startDate = '2012-01-01 00:00:00.000' 
SET @endDate = '2012-02-01 00:00:00.000' 
SET @projectNr = '1234567' 
SET @MachineNr = '2' 

SELECT 
    DATEDIFF("SECOND", 
     CASE WHEN timestamp < @startDate 
      THEN @startDate 
      ELSE timestamp 
     END, 
     CASE WHEN timestampOutOfAlarm > @endDate OR timestampOutOfAlarm IS NULL 
      THEN @endDate 
      ELSE timestampOutOfAlarm 
     END) AS Uptime 
FROM 
    [table] 
WHERE 
    timestamp < @endDate 
    AND (timestampOutOfAlarm > @startDate OR timestampOutOfAlarm IS NULL) 
    AND fileProjectNr = @projectNr 
    AND fileProjectMachineNr = @MachineNr 
    AND (failureBitNr = 't2_13' AND failureBitValue = '1') 
+0

查詢相加得到的時間機器上。現在,如何減少失敗時間..? 因爲可以同時出現更多故障,所以無論故障發生的多少,如何確定故障時間,只能從開始到結束。 – Timo002

+0

我想我找到了解決我的問題的方法。我需要解決這個問題,當我確定它沒問題時,我會發布它! – Timo002

回答

0

問題解決了:

我這樣做是在2個存儲過程或查詢的。一個用於獲得「開啓」時間,另一個用於在「開啓」時間內獲得所有「關閉」時間。這兩次我可以計算正常運行時間,停機時間和維護時間。

查詢有關時間:

<!-- language: lang-sql --> 
SELECT fctAlarmId, 
     fileProjectNr, 
     fileProjectMachineNr, 
     failureBitNr, 
     timestamp, 
     CASE WHEN timestampOutOfAlarm > @endDate OR timestampOutOfAlarm IS NULL 
      THEN @endDate 
      ELSE timestampOutOfAlarm 
     END 
     AS timestampOutOfAlarm 
INTO #tempTable1 
FROM fctAlarmHistory 
WHERE (timestampOutOfAlarm >= @startDate OR timestampOutOfAlarm = NULL) 
     AND timestamp < @endDate 
     AND failureBitValue = 1 
     AND failureBitNr = 't2_13' 
     AND fileProjectNr = @projectNr 
     And fileProjectMachineNr = @ProjectMachineNr 

-- SUM the result of all ON times into OnTime in seconds 
SELECT 
    SUM(DATEDIFF("SECOND", 
     CASE WHEN timestamp < @startDate 
      THEN @startDate 
      ELSE timestamp 
     END, 
     CASE WHEN timestampOutOfAlarm > @endDate 
      THEN @endDate 
      ELSE timestampOutOfAlarm 
     END)) AS OnTime 
FROM 
    #tempTable1 

查詢停機期間時間:

<!-- language: lang-sql --> 
SELECT fctAlarmId, 
     fileProjectNr, 
     fileProjectMachineNr, 
     failureBitNr, 
     timestamp, 
     CASE WHEN timestampOutOfAlarm > @endDate OR timestampOutOfAlarm IS NULL 
      THEN @endDate 
      ELSE timestampOutOfAlarm 
     END 
     AS timestampOutOfAlarm 
INTO #tempTable1 
FROM fctAlarmHistory 
WHERE (timestampOutOfAlarm >= @startDate OR timestampOutOfAlarm = NULL) 
     AND timestamp < @endDate 
     AND failureBitValue = 1 
     AND failureBitNr = 't2_13' 
     AND fileProjectNr = @projectNr 
     And fileProjectMachineNr = @ProjectMachineNr 

SELECT fctAlarmId, 
     fileProjectNr, 
     fileProjectMachineNr, 
     failureBitNr, 
     timestamp, 
     CASE WHEN timestampOutOfAlarm > @endDate OR timestampOutOfAlarm IS NULL 
      THEN @endDate 
      ELSE timestampOutOfAlarm 
     END 
     AS timestampOutOfAlarm 
INTO #tempTable2 
FROM fctAlarmHistory 
WHERE (timestamp BETWEEN @startDate AND @endDate) 
     AND failureBitValue = 1 
     AND (failureBitNr LIKE'f%') 
     AND fileProjectNr = @projectNr 
     And fileProjectMachineNr = @ProjectMachineNr 

CREATE TABLE #tempTable3 
(
ID int IDENTITY(1,1), 
timestamp datetime, 
timestampOutOfAlarm datetime 
) 

DECLARE failure_Cursor CURSOR FOR 
SELECT timestamp, timestampOutOfAlarm 
FROM #tempTable2 
ORDER BY timestamp ASC 

OPEN failure_Cursor 

-- Perform the first fetch. 
FETCH NEXT FROM failure_Cursor 
INTO @rij_timestamp, @rij_timestampOutOfAlarm 

INSERT INTO #tempTable3 (timestamp, timestampOutOfAlarm) VALUES(@rij_timestamp,@rij_timestampOutOfAlarm) 

-- Check @@FETCH_STATUS to see if there are any more rows to fetch. 
WHILE @@FETCH_STATUS = 0 
    BEGIN 
     PRINT @rij_timestamp 
     IF @rij_timestamp <= (SELECT TOP 1 timestampOutOfAlarm FROM #tempTable3 ORDER BY timestamp DESC) 
     BEGIN 
      IF @rij_timestampOutOfAlarm > (SELECT TOP 1 timestampOutOfAlarm FROM #tempTable3 ORDER BY timestamp DESC) 
      BEGIN 
       UPDATE #tempTable3 SET timestampOutOfAlarm = @rij_timestampOutOfAlarm WHERE ID = (SELECT TOP 1 ID FROM #tempTable3 ORDER BY timestamp DESC) 

      END 
     END 
     ELSE 
      INSERT INTO #tempTable3 (timestamp, timestampOutOfAlarm) VALUES(@rij_timestamp,@rij_timestampOutOfAlarm) 

     FETCH NEXT FROM failure_Cursor 
     INTO @rij_timestamp, @rij_timestampOutOfAlarm 
    END 
CLOSE failure_Cursor 
DEALLOCATE failure_Cursor 

-- Select the failure time. 
SELECT 
    SUM(DATEDIFF("SECOND", 
     CASE WHEN tt3.timestamp < @startDate 
      THEN @startDate 
      ELSE tt3.timestamp 
     END, 
     CASE WHEN tt3.timestampOutOfAlarm > tt1.timestampOutOfAlarm 
      THEN tt1.timestampOutOfAlarm 
      ELSE tt3.timestampOutOfAlarm 
     END)) AS DownTime 
FROM 
    #tempTable3 tt3 
INNER JOIN 
    #tempTable1 tt1 
ON 
    tt3.timestamp BETWEEN tt1.timestamp AND tt1.timestampOutOfAlarm