我正在使用一个小型的MariaDB数据库。要提取每个用户的时间间隔,我使用以下查询:
SELECT
SUM(TIMESTAMPDIFF(SECOND,Activity.startTime,Activity.endTime)) AS seconds,
TIME_FORMAT(SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND,Activity.startTime,Activity.endTime))),'%Hh %im %ss') AS formattedTime,
TSUser.name
FROM Activity
INNER JOIN User ON User.id = Activity.userID
GROUP BY User.id
ORDER BY seconds DESC;
我必须选择时间为普通秒(... AS seconds
)才能按顺序排序结果,如我的查询中所示。
但是,我也希望MariaDB格式化时间间隔,因为我使用TIME_FORMAT
函数。问题是,我必须再次复制SUM(...)
调用中的整个TIME_FORMAT
短语。这看起来并不优雅。 MariaDB会识别重复并仅计算SUM
一次吗?另外,有没有办法在不重复SUM
的情况下获得相同的结果?
我认为这应该可以使用嵌套查询结构,如下所示:
SELECT
innerQuery.name,
innerQuery.seconds,
TIME_FORMAT(SEC_TO_TIME(innerQuery.seconds), '%Hh %im')
FROM (
//Do the sum here, once.
) AS innerQuery
ORDER BY innerQuery.seconds DESC;
这是最好的方式/#34;确定"要做什么?
注意:我不需要结果中的原始秒数,只需要格式化的时间。
我很感激帮助,谢谢。
答案 0 :(得分:1)
唉。没有一个非常好的解决方案。当您使用子查询时,MariaDb实现子查询(与MySQL一样)。您的查询相当复杂,因此无论如何都会发生大量的I / O,因此额外的实现可能并不重要。
重复表达实际上更多的是美学而不是表现。表达式将被重复执行多次。但是,进行聚合的真正代价是group by
(或者使用的任何方法)的文件排序。执行sum()
两次并不是什么大问题(除非您调用的是非常昂贵的函数以及聚合函数)。
其他数据库引擎不会自动实现子查询,因此通常建议在其他数据库中使用子查询。在MariaDB / MySQL中,我猜想重复表达式会更有效率,尽管您可以同时尝试数据并报告回来。
答案 1 :(得分:1)
在此情况下,您不需要原始值。格式化的值将在ORDER BY
。
由于存在两个查询的所有开销,您的子查询想法可能会变慢。
这是一条经验法则:MySQL获取行所需的工作要比计算行中的表达式花费更多。根据该规则,重复的表达式不是负担。