0

我试图在几行中获取一些平均值和一些总和,按一天中的每个小时分组。另外,我想获取一个额外的列,其中我没有得到每个小时的总和(在分组时获取),但是我想在该特定日期之前获取所有行的总和。SQL 语句发布在下面。

我现在的问题是,在 MySQL 数据库上执行超过 25k 行的查询大约需要 8 秒(CPU i5/8GB RAM)。我发现 subselect ( ... AS 'rain_sum') 使它非常慢。我现在的问题是:我的思维方式是否过于复杂?有没有更简单的方法来获得我从下面的查询中得到的相同结果?

SELECT
    `timestamp_local` AS `date`,
    AVG(`one`) AS `one_avg`,
    AVG(`two`) AS `two_avg`,
    SUM(`three`) AS `three_sum`,
    (SELECT SUM(`b`.`three`)
        FROM `table` AS `b`
        WHERE `b`.`timestamp_local` <= SUBDATE(`a`.`timestamp_local`, INTERVAL -1 SECOND)
        LIMIT 0,1) AS `three_sum`
FROM  `table` AS  `a`
GROUP BY
    HOUR( `a`.`timestamp_local` ),
    DAY( `a`.`timestamp_local` ),
    MONTH( `a`.`timestamp_local` ),
    WEEK( `a`.`timestamp_local` ),
    YEAR( `a`.`timestamp_local` )
ORDER BY `a`.`timestamp_local` DESC
LIMIT 0, 24;
4

1 回答 1

0

而不是对所有这些领域进行分组,一个更简单(更快)的解决方案(从这里)可能是:

GROUP BY UNIX_TIMESTAMP(timestamp_local)/3600

我无法想象您的查询会返回您想要的结果(如果我正确理解您的要求)。我了解您的要求,因为当给定小时没有行时,您想要计算小时 < 该小时的所有行的总和。MySQL 不会选择空分组(对于子查询部分)。

据我所知,在 MySQL 中没有简单有效的方法来执行此操作,我建议创建一个临时表,其中包含您查看的范围内的所有可能的分组值(可能带有循环)。您可能可以提前几年设置此表,并可能根据需要添加行。然后你可以离开加入这张桌子和你的桌子。

如果您使用的是 MSSQL,则可以使用递归 CTE,尽管这可能会非常慢。查看这个或谷歌“mysql cte”以获取 MySQL 替代品。使用递归执行此操作的方法是(左)重复连接同一个表,HOUR = HOUR+1直到获得非 NULL 值,然后停止。对于其中的每一个,您将向后计算总和。

于 2012-12-28T09:21:37.083 回答