MySQL计算最后一个“封闭组”列的总和

时间:2016-01-17 19:22:40

标签: mysql sql

我有一张桌子,(为简单起见)有两个字段:

#00 value | enabled
#01 ===============
#02 100   | 1
#03 200   | 1
#04 300   | 1
#05 0     | 0
#06 0     | 0
#07 200   | 1
#08 200   | 1
#09 200   | 1
#10 100   | 1
#11 0     | 0
#12 0     | 0

每小时记录一条记录。

基本上,启用的值标记一个循环,当启用= 1时,该值表示消耗了一定量的功率(每行1小时)。当enabled = 0时,每小时仍然有一行(该值与此无关)。

问题:

我需要总结 last 完成周期的所有“值”= enabled = 1的序列。所以在上面的例子中#07-#10 = 200 + 200 + 200 + 100 = 700。

如何在SQL中完成?也许存储过程?

2 个答案:

答案 0 :(得分:1)

您可以在SQL中执行此操作。这是一种方式:

select count(*), sum(value)
from t cross join
     (select max(id) as max_prev0
      from t cross join
           (select max(id) as max_1
            from t
            where id = 1
           ) t0
      where t = 0 and t.id < t.max_1
     ) t1
where t.id > t.max_prev0 and t.id <= t.max_1;

注意:这假设您在数据中确实有一些0(虽然很容易处理NULL值。它还假设您有一个字段(在此查询中称为id)处理订购。

答案 1 :(得分:0)

感谢所有反馈和输入人员。最后,我开发了一个带有存储过程的解决方案,它看起来像这样:

CREATE DEFINER=`pleb`@`%` PROCEDURE `test`(OUT power float, OUT durationMinutes float)
BEGIN

-- used to break out of the loop --
DECLARE finished INTEGER DEFAULT 0;
-- calculates power...
DECLARE hp float;
DECLARE acOn bool;
-- variables used to track one complete cycle
DECLARE acOffFound bool DEFAULT 0;
DECLARE acOnFound bool DEFAULT 0;
-- cursor should itterate over max 1day of values (5 minutes chunks = 288 chunks per day)
DECLARE sensor_cur CURSOR FOR SELECT heatingPower, inputAcOn FROM `pleb`.`sensordata` ORDER BY timestamp DESC LIMIT 288;
-- if notihing found loop should quit right away
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
-- open the cursor
OPEN sensor_cur;
-- init zero
SET power = 0;
SET durationMinutes = 0;

-- loop over the result set
calculate: LOOP
 -- put into variables
 FETCH sensor_cur INTO hp, acOn;
 -- check if I should stop
 IF finished = 1 THEN 
  LEAVE calculate;
 END IF;
-- if we already found ac off and ac on and its off again get out of loop we are finished
 IF acOffFound = 1 AND acOnFound = 1 AND acOn = 0 THEN
  LEAVE calculate;
 END IF; 
 -- wait until we see power off first
 IF acOffFound = 0 AND acOn = 1 THEN
  ITERATE calculate;
 END IF;
 -- detect if we have seen power off
 IF acOffFound = 0 AND acOn = 0 THEN
  SET acOffFound = 1;
 END IF;
 -- detect if we found an power on
 if acOnFound = 0 AND acOn = 1 THEN
  SET acOnFound = 1;
 END IF;
 -- if its on calculate
 IF acOn = 1 THEN
  SET power = power + ( (hp * 5) / (1000*60) );
  SET durationMinutes = durationMinutes + 5;
 END IF;

 -- next cycle
 END LOOP calculate;


-- get rid of the cursor
CLOSE sensor_cur;
END