首页 > 解决方案 > 使用 group by 子句选择最旧的 HABTM 记录

问题描述

我想在管理页面(使用chartkick)上显示一个折线图,其中包含与其最早导出日期相关的分数增量。

我有以下型号:

# score.rb

class Score < ApplicationRecord
  has_and_belongs_to_many :export_orders, join_table: :scores_export_orders
end

# export_order.rb

class ExportOrder < ApplicationRecord
  has_and_belongs_to_many :scores, join_table: :scores_export_orders
end

Score对于每个至少有一个,我如何选择与最早ExportOrder的对应(仅日期格式)?ExportOrdercreated_at

我看过this,但我的情况是HABTM关系而不是简单的has_many。

我尝试了这段代码,以获得至少最旧的导出日期和分数数量之间的映射:

sql = "
SELECT
  COUNT(DISTINCT scores.id), MIN(export_orders.created_at::date)
FROM
  scores
INNER JOIN
  scores_export_orders
ON
  scores.id = scores_export_orders.score_id
INNER JOIN
  export_orders
ON
  export_orders.id = scores_export_orders.export_order_id
GROUP BY
  export_orders.created_at::date
".split("\n").join(' ')
query = ActiveRecord::Base.connection.execute(sql)
query.map { |v| [v['count'], v['min']] }

但总分数大于所有具有导出日期的分数。有任何想法吗?

标签: sqlruby-on-railspostgresqlactiverecordruby-on-rails-5

解决方案


尝试:

class Score < ApplicationRecord
  has_and_belongs_to_many :export_orders, join_table: :scores_export_orders

  def earliest_export_date
    export_orders.pluck(&:created_at).min
  end
end

这将让您调用@score.earliest_export_date,它应该返回您想要的值。

我也认为这是在 ruby​​ 中执行此操作的最高效方式,尽管有人可能会纠正我。


推荐阅读