1

基準条件が満たされた期間に生産された規格外製品を合計 (合計) する必要があるアプリケーションがあります。これを説明する最も簡単な方法は、例を使用することです。

データは、列を持つ 1 つのテーブルt_dataに存在します:
- tagId (Nvarchar)
- timeStamp (Datetime)
- valueFloat (Float)

合計する値の tagId はmyValで、基準値はmyCritです。myCritが 10 未満のときはいつでも、 myValの合計値を知りたいです。

tagId    |  timeStamp  |  valueFloat  |  (comment)  
---------+-------------+--------------+--------------   
myCrit   |  08:01:00   |  12.0        |  myCrit starts good - no totalizing yet
myVal    |  08:01:00   |  10.0        |  
myCrit   |  08:02:00   |  9.0         |  myCrit goes bad take next myval as "start"
myVal    |  08:03:00   |  15.0        |  start
myCrit   |  08:04:00   |  8.5         |  
myVal    |  08:05:00   |  16.0        |  
myVal    |  08:06:00   |  20.0        |  end (20-15 totalized)
myCrit   |  08:07:00   |  10.5        |  myCrit is good take prev. myVal as "end"
myVal    |  08:08:00   |  25.0        |  
myCrit   |  08:09:00   |  9.0         |  myCrit bad take next myVal as "start"
myVal    |  08:10:00   |  30.0        |  start
myVal    |  08:11:00   |  40.0        |  end (40-30 totalized)
myCrit   |  08:12:00   |  11.0        |  myCrit good, take prev. myVal as "end"

表示されるデータ範囲のクエリの合計値は、(20-15 + 40-30) = 15 になります。

要約すると、時間セグメントの開始時と終了時に myVal の差を追加したいと思います。セグメントの開始と終了は、myCrit の良い値または悪い値への変化によってマークされます。ストアドプロシージャでこれを行うにはどうすればよいですか?

4

1 に答える 1

0

Dang...まあ、カーソルは常に最後の結果であるべきだと思いますが、サンプルデータで見たものに基づいて、ここでは意味があるかもしれません. これは機能します:

DO language plpgsql $$
DECLARE mycursor CURSOR FOR SELECT tagId, valueFloat FROM t_data ORDER BY time_stamp;
DECLARE critval float = 10;
DECLARE last_bad boolean = false;
DECLARE gonecritical boolean = false;
DECLARE startval float = -9999;
DECLARE endval float = 0;
DECLARE totalized float = 0;
DECLARE ltagid varchar;
DECLARE lvalue float;
BEGIN
    OPEN mycursor;
    FETCH NEXT from mycursor INTO ltagid, lvalue;
    WHILE (FOUND) LOOP
      /* We have a record */

        /* Are we critical already or not? */
        if gonecritical then
            /* We are already in a critical chunk */
            IF ltagid = 'myVal' and startval = -9999 THEN
                startval = lvalue;
            END IF;
            if ltagid = 'myVal' then
                /* The "last" one we did will always be endval */
                endval = lvalue;
            END IF;
            if ltagid = 'myCrit' and lvalue >= critval then
                /* Yeah! This is the end of critical! */
                totalized = totalized + (endval - startval);
                goneCritical = false;
                startval = -9999;
            END IF;
        else
            /* We are NOT already in a critical chunk */
            if ltagid = 'myCrit' and lvalue < critval then
                /* Yikes we are going critical */
                gonecritical = true;
            END IF;
        end if;

        FETCH NEXT from mycursor INTO ltagid, lvalue;
     END LOOP;
     CLOSE mycursor;
     INSERT INTO t_result select totalized;
END;
 /* totalized has your value! */

$$

私は Postgres でそれを行いましたが、非常に一般的な SQL ベースのクエリ構文を使用したため、MSSQL や必要なもので簡単に使用できるはずです。

幸運を!デイブ

于 2013-07-23T13:32:58.660 に答える