【问题标题】:Milliseconds convert and get year毫秒转换并获得年份
【发布时间】:2017-11-21 03:44:47
【问题描述】:

我有一个包含以毫秒为单位的日期的 BIGINT。我希望按选定列created_at 的年份过滤记录。我使用 MYSQL 作为我的数据库。

这是我目前在控制器中所拥有的。

@agent = Agent.where('Time.at(created_at/1000).year = ?', '2017')

提供以下错误:

Mysql2::Error: You have an error in your SQL syntax

【问题讨论】:

    标签: mysql ruby-on-rails ruby-on-rails-5


    【解决方案1】:

    数据库不理解像 Time.at(created_at/1000).year 这样的 Ruby 代码,所以你不能在这样的 where 调用中使用它,where 的这种形式适用于 SQL的 sn-ps >,而不是 Ruby

    您可以让数据库从“自纪元以来的毫秒数”created_at 值中提取年份。您可以使用 MySQL 的 from_unixtime 函数和适当的格式字符串一步完成:

    Agent.where("from_unixtime(created_at/1000, '%Y') = ?", '2017')
    

    这与您尝试将 Ruby 代码发送到数据库的内容几乎相同。

    当然,您可能更喜欢在 Ruby 中完成这项工作,就像在 Charlie Weems's answer 中一样。

    如果您经常这样做,并且 WHERE 子句中没有其他内容可以减少您正在查看的行数,您可能需要比较每种方法与您拥有的任何索引的交互方式。

    【讨论】:

    • 两个答案都是可靠的。但是这种方法更适合我的需要。感谢您的帮助!
    【解决方案2】:

    除非你知道,否则我认为你不能在这样的 where 比较中做 Time.at

    一种方法是反转比较,并将年份转换为自纪元以来的毫秒数:

    comparison_time = (Time.new(2017, 1, 1).to_f * 1000).to_i
    @agent = Agent.where("created_at = ?", comparison_time)
    

    注意:如果您的行的时间戳与年份完全一致,您可以像示例中那样使用相等比较。否则,您可能需要开始日期和结束日期,以便返回范围。示例:

    start_time = (Time.new(2017, 1, 1).to_f * 1000).to_i
    end_time = (Time.new(2018, 1, 1).to_f * 1000).to_i
    @agent = Agent.where("created_at >= ? AND created_at <= ?", start_time, end_time)
    

    另一种方法是遍历所有代理,将每个代理的 created_at 转换为 DateTime 并与 2017 年进行比较。但是,如果您有一个大表,这可能会占用大量内存,因为 Rails 会做操作而不是 MySQL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 2011-10-28
      相关资源
      最近更新 更多