2012-09-05 3 views
3

У меня есть набор с данными в базе данных SQL Server, и мне нужно рассчитать время безотказной работы машины. Я использую две переменные для определения времени безотказной работы или простоев. Эти две переменные: machine_ON и failure(s). machine_ON - это только одна переменная в базе данных, failure может быть 64 различных сбоя, но все указывает как fx_x.SQL Server query 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].

Чтобы определить время безотказной работы, мне нужно получить timediff между timestamp и timestampOutOfAlarm, где 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 хранимых процедур или запроса. Один для получения времени «ON» и один для получения всего времени «DOWN» в течение времени «ON». В эти два раза я могу рассчитать время безотказной работы, время простоя, время обслуживания.

Запрос на время включения:

<!-- 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