mysql - Activerecord:将 ruby​​ 方法转移到 sql-land

标签 mysql ruby-on-rails ruby activerecord

我在 Rails 应用程序中有以下架构 enter image description here

我的页面有很多加载时间(这是一个多态关联)。我想获取每个页面的最新 created_at load_time,然后从中获取最大 load_time 字段编号(希望同名字段不会让您感到困惑)。这是我目前所拥有的,但使用了 ruby​​ 方法:

pages.includes(:load_times).group(:resource_id).select("load_times.load_time, max(load_times.created_at) as date").reject{|lt| lt.load_time.nil?}.sort_by { |pg| pg.load_time.load_time }.last

如何将 rejectsort_by ruby​​ 方法转移到 sql land?

最佳答案

这个怎么样:

pages
.joins(:load_times)
.group(:resource_id)
.select("pages.*, load_times.load_time, MAX(load_times.created_at) as date")
.where.not(load_times: { load_time: nil })
.order("load_times.load_time")
.last

请注意,where.not 仅适用于 Rails >= 4。如果您使用的是 Rails 3,则可以将其替换为 where("load_times.load_time IS NOT NULL")


在评论中明确了想要的结果后,这是获取所有 load_time 最慢的 Page 对象的查询,仅考虑最近的 load_time 记录的 load_time。请注意,您通常可以在带有 MAX(load_times.created_at) 或带有 MAX(load_times.id) 的 having 子句中获得该结果,两者无法区分,后者更多一些高效的。如果这样做,请将所有对 created_at 的引用更改为 id

pages
.joins(:load_times)
.where.not(load_times: { load_time: nil })
.group('load_times.created_at')
.having('load_times.created_at = MAX(load_times.created_at)')
.order('load_times.load_time DESC')
.first

编辑

经过更多研究(是的,我个人认为 ;)),我终于让您的查询正常工作。您需要两次连接 load_times 表,使用连接条件中每个 Page 的最后一行。

此外,对于第二次连接,您需要使用单个列来标识 load_times 的最后一个条目。 created_at 可能无法正常工作,因为您的 load_times 表可能有两个具有相同 created_at 的条目。也许这不是你的情况,但以防万一我使用了 id,因为它与 created_at 具有相同的顺序并且是唯一的。

此外,我删除了 where.not(load_times: { load_time: nil }) 位,因为我假设您想要在其上获取最后一个 load_time 元素具有 load_time 属性。

最后,我假设了一个多态关联,因此 resource_type = 'Page'

这里是:

pages
.joins(:load_times)
.joins("INNER JOIN (SELECT l1.page_id, MAX(l1.id) AS max_id FROM load_times as l1 GROUP BY l1.page_id) l2 ON load_times.page_id = l2.page_id AND load_times.id = l2.max_id AND resource_type = 'Page'")
.order("load_times.load_time DESC")
.first

感谢发人深省的问题,学到了很多。

关于mysql - Activerecord:将 ruby​​ 方法转移到 sql-land,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28609293/

相关文章:

php - 尝试插入 mysql 数据库忽略空白字段

ruby-on-rails - 在 Ruby on Rails 中为一个模型设置两个 Controller 是不好的做法吗?

ruby-on-rails - 来自 Rails Heroku 的 Facebook Open Graph

ruby - 使用 ruby​​-libxml 在 root 之外添加注释节点

sql - 如何正确转换或查询 Rails/MySQL DateTime 列的日期范围

php - 连接具有第一个表中的重复项的表 Code Igniter Active Records

php - 如何使用 CakePHP 3 连接多个表?

mysql - 如何将 SQL 查询转换为 Eloquent Laravel

ruby-on-rails - Newb 正则表达式问题 - Ruby 1.9.2

ruby-on-rails - Time.use_zone 未按预期工作