存储过程返回计算结果集

时间:2012-08-16 07:13:13

标签: mysql sql stored-procedures cursor

我有一张这样的表

from   | to     | value
-----------------------
08:10  | 08:12  | 2
08:13  | 08:20  | 5
08:30  | 08:45  | 3
08:46  | 08:55  | 1

我需要按照1,10,60分钟的间隔进行分组并获得平均值,假设每分钟有一个值。

注意:范围之间存在漏洞,从包含端到非包含端

from   | to     | average_value
-----------------------
08:10  | 08:19  | 4
08:20  | 08:29  | 5
08:30  | 08:39  | 3
08:40  | 08:49  | 2
08:50  | 08:59  | 1

我的想法是使用存储过程将条目转换为

time   | value
-----------------------
08:10  | 2
08:11  | 2
08:12  | 2
08:13  | 5
...
08:20  | 5
08:30  | 3
...
08:45  | 3
08:50  | 1
...
08:55  | 1

我的第一次尝试

DELIMITER $$
CREATE PROCEDURE Decompose()
BEGIN
    DECLARE num_rows INT;
    DECLARE from DateTime;
    DECLARE to DateTime;
    DECLARE value double;

    DECLARE friends_cur CURSOR FOR SELECT from, to, value FROM sourcetable;

    -- 'open' the cursor and capture the number of rows returned
    -- (the 'select' gets invoked when the cursor is 'opened')
    OPEN friends_cur;
    select FOUND_ROWS() into num_rows;

    WHILE num_rows > 0 DO

        FETCH friends_cur INTO  from, to, value;

        SELECT from, value;

        SET num_rows = num_rows - 1;
    END WHILE;

    CLOSE friends_cur;
END$$
DELIMITER ;

导致'命令不同步'错误,因为循环中的每个SELECT都会每次创建一个新的结果集,而不是返回一行。

问题:

  • 我可以以某种方式使存储过程工作吗?
  • 是否有可能获得每个间隔的平均值的SQL?

2 个答案:

答案 0 :(得分:1)

我认为你的基本计划是合理的。

我首先要创建一个数字表。 (Creating a "Numbers Table" in mysql

从那里开始,将其转换为一个表,其中包含您希望计算平均值的每一分钟的行数 - 包括那些没有任何值的值 - 以及一个用于指示特定分钟属于哪个时间间隔的列到

Time     Interval
08:00    1
08:01    1
08:02    1
08:03    1
08:04    1
08:05    2
08:06    2
....

从左边开始使用

连接到样本表
ON intervals.Time >= Samples.Time and intervals.Time<Sample.Time

生成间隔的查询,然后对其进行平均。

我认为你不需要光标。

(我会给出更具体的例子,但我不了解一些MySql的各种SQL复杂性)

答案 1 :(得分:0)

可能是您可以在一个查询中尝试这样的事情:

SELECT DATE_FORMAT(TIMEDIFF('08:12','08:10'), '%m') AS time, AVG(value) avg_value
FROM table_name
GROUP BY 1
ORDER BY avg_value DESC;