我正在尝试获取一些平均值和几行的总和,按一天中的每个小时进行分组。另外我想获取一个额外的列,其中我没有获得每小时的总和(在分组时获取),但是我想要获取所有行的总和,直到该特定日期。 SQL语句发布在下面。
我现在的问题是,在超过25k行的MySQL数据库上执行查询大约需要8秒(CPU i5 / 8GB RAM)。我发现子选择(... 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;
答案 0 :(得分:0)
不是对所有这些字段进行分组,而是一个更简单(更快)的解决方案(来自here)可能是:
GROUP BY UNIX_TIMESTAMP(timestamp_local)/3600
我无法想象您的查询会返回您想要的结果(如果我正确理解您的要求)。我理解你的要求,因为当给定小时没有行时,你想要计算所有行的总和,小时&lt;那个小时。 MySQL不会选择空分组(对于子查询部分)。
在我所知道的MySQL中没有简单有效的方法可以做到这一点,我建议创建一个临时表,其中包含您所查看范围内的所有可能的分组值(可能带有循环)。您可以预先设置此表几年,并可能根据需要添加行。然后你可以离开加入这张桌子和你的桌子。
如果您使用的是MSSQL,那么您可能已经使用了递归CTE,尽管这可能非常慢。对于MySQL替代品,请查看this或google“mysql cte”。使用递归执行此操作的方法是(左)重复连接同一个表HOUR = HOUR+1
,直到获得非NULL值,然后停止。对于其中的每一个,您将向后计算总和。