【问题标题】:Active Record - select with SQL returns string instead of original classActive Record - 使用 SQL 选择返回字符串而不是原始类
【发布时间】:2018-09-14 17:18:42
【问题描述】:

我有一个用户和约会数据库。约会具有 TimeWithZone 格式的 start_timeend_time。我想确定哪些用户已超过某个总持续时间。不幸的是,约会表没有内置持续时间,所以我必须自己计算。

如果我从 end_time 中减去 start_time,它会返回一个浮点数,这对我来说是完美的。

Appointment.first.end_date - Appointment.first.start_time
=> 3600.0
(Appointment.first.end_date - Appointment.first.start_time).class
=> Float

如果我在整个表上运行它并尝试创建一个新列,它会返回一个字符串:

Appointment.select("end_time - start_time as duration").first.duration
=> "01:00:00"
Appointment.select("end_time - start_time as duration").first.duration.class
=> String

我不确定为什么类型会改变以及如何将其转换回浮点数或任何更容易处理的类。理想情况下,我的最终查询类似于:

User.joins(:appointments).select("users.id", "end_time - start_time as duration").group("users.id").having("SUM(duration) >= ?", timelimit)timelimit取决于最长持续时间和我得到的单位

1) 为什么对于非常相似的命令会得到不同的结果

2) 如何根据结束和开始时间创建一个新列,表示每个约会的持续时间?

【问题讨论】:

  • start_date 和 start_time 有区别吗? Appointment.select("end_time - start_time as duration").first 返回什么?
  • 您在 Ruby 中减去 Dates,但在数据库中减去 times。

标签: sql ruby-on-rails time rails-activerecord


【解决方案1】:

您会得到不同的结果,因为一个由 Ruby 完成,另一个由 SQL 完成。没有理由两者都应该做同样的事情。

如果你使用 MySQL https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_time-to-sec,你可以使用 TIME_TO_SEC

Appointment.select("TIME_TO_SEC(end_time - start_time) as duration")

TIME_TO_SEC 将字符串“01:00:00”转换为秒。

mysql> SELECT TIME_TO_SEC("01:00:00");
+-------------------------+
| TIME_TO_SEC("01:00:00") |
+-------------------------+
|                    3600 |
+-------------------------+
1 row in set (0,05 sec)

【讨论】:

  • 谢谢!如果它与将来发现此问题的任何人相关,则 postgres 没有 TIME_TO_SEC,因此您必须使用 Appointment.select("EXTRACT (EPOCH FROM end_time - start_time) as duration") stackoverflow.com/questions/2816544/…
猜你喜欢
  • 2012-10-25
  • 2014-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-22
  • 2010-10-11
  • 1970-01-01
  • 2017-12-29
相关资源
最近更新 更多