Rails中如何将time类型列值转秒后按相同日期统计总和
问题原因
你原先的写法错误原因是Time.parse(:hours)是在Ruby代码执行阶段直接运行的,不会被代入到SQL查询逻辑里,:hours是Symbol类型,不符合Time.parse要求的时间字符串入参规范,所以触发类型转换报错。同时ActiveRecord的sum方法如果传入的是非字符串/符号的字段参数,无法正确生成SQL聚合逻辑。
可行实现方案
方案1:数据库层面聚合计算(推荐,性能更高,适合大数据量)
直接通过SQL原生函数计算每条记录的hours字段转秒值再求和,不用把全量数据加载到Ruby内存中:
MySQL 适配写法
total = Log.on_this_day(@log.date).sum("HOUR(hours) * 3600 + MINUTE(hours) * 60 + SECOND(hours)")
PostgreSQL 适配写法
total = Log.on_this_day(@log.date).sum("EXTRACT(EPOCH FROM hours)::integer")
返回值就是对应日期所有记录的hours转秒后的总和,你的示例数据会返回18000(即5小时对应的秒数)。
方案2:Ruby层面遍历计算(写法简单,适合小数据量)
先查出指定日期的所有日志,再遍历每条记录累加转秒后的数值:
total = Log.on_this_day(@log.date).sum { |log| log.hours.utc.seconds_since_midnight }
这里sum是Ruby可枚举对象的方法,会遍历每条log记录,调用其hours字段的转秒逻辑再累加,避免了SQL语法适配问题。
补充说明
如果你的hours字段本身已经是Rails识别的time类型,直接调用log.hours.seconds_since_midnight也可以拿到秒数值,不需要额外做Time.parse转换。
内容的提问来源于stack exchange,提问作者K. Eclipse
相关产品推荐
相关产品推荐

