【问题标题】:How to order records based on a sub-sample of association counts?如何根据关联计数的子样本对记录进行排序?
【发布时间】:2013-05-28 15:26:27
【问题描述】:

在 Rails 3.2 中说我有 3 个模型:Athlete、Event 和 Country

Class Athlete
  has_many :events
  has_many :countries, through: :event
end

Class Event
  belongs_to :athlete, counter_cache: true
  belongs_to :country, counter_cache: true
end

Class Country
  has_many :events
  has_many :Athletes, through: :event
end

所以我现在可以轻松地生成一个按照他们参加的赛事数量排序的运动员数组。

scope :ranked, :order => 'athletes.events_count DESC' 

但是,如果我需要一组在特定国家/地区参加过比赛的运动员,并按照他们在该国家/地区的比赛次数排序。

#country
def show
  @country.find(params[:id])
  @athletes_leaderboard = Athlete.includes(:events).where(id: @country.events.uniq.map(&:athlete_id)).ranked
end

为我提供了在该国家/地区进行过比赛的运动员的唯一列表,但它是按他们的事件数排名的,而不是按他们所在国家/地区的事件数。

如何在保持数据库性能的同时按国家/地区事件计数排序。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    查询涉及与子查询的位连接。

    country_id = params[:id]
    subsql = Event.select("events.athlete_id AS a_id, count(events.id) AS country_event_count").where("events.country_id = ?", country_id).group("a_id").to_sql
    @athletes_leaderboard = Athlete.joins("JOIN (#{subsql}) AS participated_events ON participated_events.a_id = athletes.id").
      order("participated_events.country_event_count DESC")
    

    @athletes_leaderboard 的结果不再是ActiveRecord::Relation。它是数据库结果行。您将需要遍历结果并将其呈现在您的视图中。例如(使用 HAML):

    - @athletes_leaderboard.each do |athlete_data|
      = link_to athlete_data["name"], athlete_path(athlete_data["id"])
    

    您可能希望将排行榜缓存在内存存储(如 Memcache)中,这样数据库就不会经常受到攻击。

    【讨论】:

    • 这看起来很有希望,但我收到了ActiveRecord::StatementInvalid: PG::Error: ERROR: syntax error at or near "SELECT",而且我还不够了解,无法调试它。我做错了什么?
    • 让我再调试一次。同时,你能显示puts @athletes_leaderboard.to_sql的输出吗?
    • 我错过了JOIN。你能再试一次吗?
    • 感谢 catcyborg,这似乎有效,而且我学到了一些新东西!你能帮我理解更多吗?您将如何修改它以适应祖父母关系?例如,Continent has_many :countries,并显示一个大陆的排行榜。谢谢!
    猜你喜欢
    • 2020-04-16
    • 1970-01-01
    • 2018-03-25
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    相关资源
    最近更新 更多