3

SQL Serverデータベースにデータのセットがあり、マシンの稼働時間を計算する必要があります。稼働時間またはダウンタイムを決定するために2つの変数を使用しています。これらの2つの変数はとmachine_ONですfailure(s)machine_ONはデータベース内の1つの変数のみであり、failure64の異なる障害になる可能性がありますが、すべてがとして示されfx_xます。

これらの変数のステータス情報は、次のようにデータベースに保存されます。

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.0002012-01-17 10:39:05.000

また、machine_ON状態は同じ方法で同じテーブルに保存されますfailurebitNrが、値が異なる[ t2_13]のみです。

したがって、稼働時間を決定するには、との間の時間差timestampから障害時間timestampOutOfAlarmを差し引いたものを取得する必要があります。failurebutNr = 't2_13'

たとえば、データベースにこれらの行があります。

表表現の画像をクリックしてください

これにより、次のグラフィック表現が得られます。

データサーのグラフィック表現

緑は稼働時間、赤はダウンタイムです。

私はPHPで作業することに慣れており、whileループを使用していくつかの配列をファイルし、他のスクリプトを実行します。しかし今、私はこれをすべてSQLServerデータベースでクエリ方式で実行する必要があります...

では、アップタイム(緑)とダウンタイム(赤)をどのように計算できますか?

アップデート

マシンがオンになっている時間を秒単位で取得しようとしました。私はこのクエリを使用しました:

<!-- 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')
4

1 に答える 1

0

問題が解決しました:

2つのストアドプロシージャ、つまりクエリで実行しました。1つは「ON」時間を取得するためのもので、もう1つは「ON」時間内のすべての「DOWN」時間を取得するためのものです。これらの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
于 2012-09-10T09:23:59.303 に答える