我收集了Cost
条记录,并希望选择特定费用并按天分组
我试过这个
@costs = Cost.where(source:(params[:source]),month:params[:month]).group(:day).order('created_at ASC')
但在此之后我得到ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "costs.id" must appear in the GROUP BY clause or be used in an aggregate function
我的目标是获取特定记录并按天分组
例如我有少量记录15月1日我可以在这一天添加多条记录,所以我需要将它们组合在一起
或者您可以建议任何其他解决方案
db - psql (PostgreSQL) 9.4.5
rails - Rails 4.2.5
答案 0 :(得分:2)
如果要使用group
,则必须在组上添加一种计算或聚合函数。要获取分组记录,请先尝试获取分组ID,然后只能获取具有给定ID的记录:
groups = Cost.group(:day).select('array_agg(id) as ids, day').limit(100).to_a
last_day_group = groups.last
# now you can get ids array and day value
puts last_day_group.day
# => 'Monday'
puts last_day_group.ids
# => [1, 2, 3, 45]
# get Cost records by day:
Cost.where(id: last_day_group.ids)
答案 1 :(得分:1)
这是因为您以错误的方式使用该组。您上面的代码将由Rails翻译成sql语句,即
select * from cost where source = value and month = value group by day order by created_at asc
这是一个无效的sql语句,因为您正在选择表中的所有字段,并且它们都不属于任何聚合函数或group by子句。
请查看此link以获取有关如何编写正确的分组条款的详细信息。
这是一个正确转换为sql语句的Rails代码示例,其中包含group by子句的用法。
Order.select("COUNT(id) as num, payment_method, purchase_price, selling_price, xcount").where("multiplex_id = ? AND created_at >= ? AND created_at <= ? AND state = ?", multiplex_id, start_date, end_date, 'reserved').group(:payment_method, :purchase_price, :selling_price, :xcount)
如您所见,我已指定了我需要检索的所有字段,所有这些字段都是聚合函数的一部分或由group by子句使用。
答案 2 :(得分:0)
您可能会混淆ActiveRelation#group
这是一个SQL子句而Array#group_by
会根据一个值对数组的块进行分组。因此,在您的情况下,您只需要以这种方式重写它:
# in your controller
@costs = Cost.where(source:(params[:source]),month:params[:month]).order('created_at ASC')
# in your view
- @costs.group_by(&:date) do |date, n_costs|
= date
- n_costs.compact.each do |cost|
%p= cost.source
# etc