DELIMITER $$DROP PROCEDURE IF EXISTS`historical_data_period`$$CREATE PROCEDURE `historical_data_period`(IN start_time_cur VARCHAR(32),IN end_time_cur VARCHAR(32))BEGIN
--定义变量--事务 游标 变量
DECLARE station_code2 VARCHAR(32) DEFAULT NULL; --热站编码
DECLARE heat_area_design2 VARCHAR(32) DEFAULT NULL; --热站编码
DECLARE min_time DATETIME DEFAULT NULL;--起始时间`read_time`当天最早的一条记录
DECLARE max_time DATETIME DEFAULT NULL;--结束时间`read_time`当天最晚的一条记录
DECLARE min_heat_value DOUBLE(255,2) DEFAULT NULL;--min_time对应的表值
DECLARE max_heat_value DOUBLE(255,2) DEFAULT NULL;--max_time对应的表值
DECLARE heat_consumption_count DOUBLE(255,2) DEFAULT NULL; --耗热量
DECLARE day_count INT(8) DEFAULT TO_DAYS(end_time_cur) - TO_DAYS(start_time_cur);--定义时间间隔
DECLARE stopFlag INT DEFAULT 0;--设置游标默认循环
--将结束标志绑定到游标
DECLARE CONTINUE HANDLER FOR NOT FOUND SET stopFlag = 1;--当查不到数据时,关闭游标
--手动开启事务
START TRANSACTION;--清除表中上次存储的查询数据
TRUNCATE TABLE`period_data`;
--
-- 设置按时间*/
WHILE( day_count>= 0) DOIF(EXISTS(SELECT * FROM `historical_data` WHERE TO_DAYS(end_time_cur) - TO_DAYS(read_time)=day_count)) THEN --第一天
BEGIN -- 保证游标定义能在后面!
--定义游标
DECLARE start_time_count CURSOR FOR --当天记录的最早一条数据
SELECT MIN(`read_time`),`heat_station_code`FROM`historical_data`WHERE TO_DAYS(end_time_cur) - TO_DAYS(read_time)=day_countGROUP BY `heat_station_code`; --按热站编码生成3行数据
DECLARE end_time_count CURSOR FOR --当记录的最晚一条数据
SELECT MAX(`read_time`)FROM`historical_data`WHERE TO_DAYS(end_time_cur) - TO_DAYS(read_time)=day_count AND heat_station_code=station_code2;
-- 改变的地方>--打开游标
OPENstart_time_count;
read_loop: LOOP--取值 取多个字段
FETCH start_time_count INTOmin_time,station_code2;IF stopFlag =1 THENLEAVE read_loop;END IF;--你自己想做的操作
SELECT `heat_value` INTO min_heat_value FROM `historical_data` WHERE read_time=min_time AND heat_station_code=station_code2 ;--第二个游标
OPENend_time_count;
next_loop: LOOP--取值 取多个字段
FETCH end_time_count INTOmax_time;IF stopFlag=1 THENLEAVE next_loop;END IF;--你自己想做的操作
SELECT `heat_value` INTO max_heat_value FROM `historical_data` WHERE read_time=max_time AND heat_station_code=station_code2 ;SET heat_area_design2=(SELECT `heat_area_design` FROM `historical_data` WHERE `heat_station_code`=station_code2 AND `read_time`=min_time);SET heat_consumption_count= max_heat_value -min_heat_value;--若计算出来的能耗量为null或为负值,赋值为0
IF(heat_consumption_count IS NULL||heat_consumption_count <0 ) THEN
SET heat_consumption_count=0;END IF; --heat_consumption_count IS NULL
--插入热站信息
/** 如果计算耗热率时为分母为0,设置耗热率为0
TRUNCATE 小数点后两位的数,直接截断
虽然格式是 SELECT..from..,但INSERT INTO的字段可以不是from表中的字段
WHERE中 `read_time`=min_time也可以改为`read_time`=max_time
因为从historical_data中的SELECT的字段,只有heat_station_code,heat_station_code只受WHERE `heat_station_code`=station_code2限制,不受AND `read_time`=min_time;时间限制
AND `read_time`=min_time不可以省略。因为`heat_station_code`=station_code2的记录每天都有,`heat_station_code`=station_code2的记录有很多行,AND `read_time`=min_time保证不取重复的热站编码*/
IF(heat_area_design2 IS NOT NULL) THEN
INSERT INTO`period_data`(`heat_station_code`,`heat_meter_start_value`,`heat_meter_end_value`,heat_consumption,heat_area_design,heat_rate)SELECT `heat_station_code`,min_heat_value,max_heat_value,heat_consumption_count,heat_area_design2,TRUNCATE(heat_consumption_count/(heat_area_design2),2)FROM`historical_data`WHERE`heat_station_code`=station_code2 AND `read_time`=min_time;ELSE
INSERT INTO`period_data`(`heat_station_code`,`heat_meter_start_value`,`heat_meter_end_value`,heat_consumption,`heat_area_design`,heat_rate)SELECT `heat_station_code`,min_heat_value,max_heat_value,heat_consumption_count,heat_area_design2,0
FROM`historical_data`WHERE `heat_station_code`=station_code2 AND `read_time`=min_time;END IF;--day_time_difference!=0
ENDLOOP next_loop;CLOSEend_time_count;/*第二个游标 // 内循环游标指到最后一条数据,再继续,便会not found,关闭游标,
内外循环共用一个stopFlag,
要进入外循环,必须打开游标,*/
SET stopFlag=0;ENDLOOP read_loop;CLOSEstart_time_count;
--
END IF;SET day_count=day_count-1;END WHILE;
-- 改变的地方>COMMIT;END$$
DELIMITER ;