【问题标题】:Join on a subquery with grouped by in Arel?在 Arel 中加入分组依据的子查询?
【发布时间】:2012-04-20 21:01:53
【问题描述】:

我在这里搜索了很多,但找不到类似的主题:我需要在 Arel 中编写一个查询,因为我使用 will_paginate 来浏览结果,所以我在使用原始 SQL 实现时会松懈很多。

这是我需要用 Arel 拼写的内容:

SELECT m.*
 FROM   messages m
 JOIN  (SELECT tmp.original_id as original_id,
               max(tmp.id) as id
        FROM   messages tmp
        WHERE  tmp.recipient_id = ?
        GROUP BY tmp.original_id) g ON (m.id = g.id)
 ORDER BY m.updated_at DESC;

简而言之:子查询检索用户的所有消息。如果一条消息有较新的回复(在回复中,我将引用消息 id 保存为 original_id),旧的将被忽略。对于所有这些消息的结果,我希望 Rails 向我提供相应的对象。

我在 SQL 方面相当熟练,但不幸的是,我不熟悉 Arel。任何帮助将不胜感激。

【问题讨论】:

    标签: ruby-on-rails-3 activerecord arel


    【解决方案1】:

    这样的事情怎么样?

    class Message < ActiveRecord::Base
      scope :newer_messages lambda { |num_days=10| where("updated_at > #{Time.now} - #{num_days}.days") }
    end
    

    然后您可以像这样为给定用户找到更新的消息:

    Message.find_by_user_id(user_id).newer_messages  
    

    【讨论】:

    • 有趣的想法。尽管这可能可行,但出于性能原因,我选择了另一个选项,并让数据库通过触发器函数预先计算最新的回复。感谢您的努力。
    • 当您像这样链接调用时,只会向数据库发出一个选择查询。 (因为它们在一个范围内执行)。您可以从服务器日志中观察到这一点。我只是提到这一点,以防您认为它正在发出多个选择查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-07
    相关资源
    最近更新 更多