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... 好吧,我认为 Cursors 应该始终是最后一个结果,但根据我在您的示例数据中看到的内容,它们在这里可能有意义。这有效:

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 回答