【问题标题】:Query for results ordered by column of association table, most recent association only查询按关联表列排序的结果,仅最近的关联
【发布时间】:2011-04-23 12:39:14
【问题描述】:

给定以下架构

class User
  has_many :page_views
  #[id]
end

class Page
  has_many :page_views
  #[id]
end

class PageView
  belongs_to :user
  belongs_to :page
  #[id, created_at, updated_at]
end

我如何查询给定页面,所有用户按 created_at 日期排序最近的页面浏览量。每个用户一行,仅显示他们最近的视图。

【问题讨论】:

    标签: ruby-on-rails sorting mysql


    【解决方案1】:

    您希望特定 page_id 的每个 user_id 具有最大 created_at 的 PageView。这是此查询在 SQL 中的表示:

    SELECT max(created_at) AS last_visit, page_views.* 
    FROM page_views 
    WHERE (page_id = 1) 
    GROUP BY user_id 
    ORDER BY last_visit DESC
    

    在 Rails 3 中,你可以这样写:

    Page.first.page_views.group(:user_id).select('max(created_at) AS last_visit, page_views.*').order('last_visit DESC')
    

    【讨论】:

    • 我的选择部分有问题。如果我取出“,*”,则查询有效,当我将其添加回来时,它会中断。我怎样才能得到 * 和 last_visit?
    • 为选择组件尝试“max(created_at) AS last_visit, page_views.*”。我在上面更新了。
    • 它也可以将 * 放在首位,例如"SELECT *, max(created_at) AS last_visit FROM"
    • 为什么 last_visit 字段被返回为字符串而不是日期时间?
    【解决方案2】:

    试试这个:

    class Page
      has_many :page_views
      has_many :recent_page_views, :class_name => "PageView",
        :joins => "INNER JOIN (
          SELECT     a.id, COUNT(*) AS ranknum
          FROM       page_views AS a
          INNER JOIN page_views AS b ON a.user_id = b.user_id AND 
                                        a.page_id = b.page_id AND 
                                        a.created_at <= b.created_at
          GROUP BY   a.id
          HAVING COUNT(*) = 1
        ) AS d ON (page_views.id = d.id)",
        :order => "page_views.created_at"
    
     has_many :recent_viewers, :through => :recent_page_views, 
                :source => :user, :order => "page_views.created_at"
    end
    

    现在

    page.recent_viewers
    

    【讨论】:

    • 也感谢您的回答!我选择了另一个简单的,但我也很欣赏你的回答。
    • 如果您需要访问任何User 模型属性,那么这个解决方案会更好。在另一种解决方案中,如果您必须获取用户的详细信息,则会对 DB 进行 N 次访问。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 2017-04-05
    • 2016-04-29
    • 2015-04-14
    相关资源
    最近更新 更多