2016-01-22 3 views
0

У меня есть коллекция Cost записей и хочет, чтобы выбрать конкретные расходы и сгруппировать их по днямRails, где и группа пункт

я попытался это

@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 января я могу добавить несколько запись в этот день, так что мне нужно сгруппировать его вместе

Или может быть, вы можете предложить любые другие решения,

дб - psql (PostgreSQL) 9.4.5

рельсы - Rails 4.2.5

+0

Try 'Cost.where (источник: Params [: источник], месяц: Params [: месяц]). group ('cost.id',: day) .order ('created_at ASC') ' –

ответ

0

Это потому, что вы используете в неправильном порядке. You выше код будет переведен Rails в SQL заявления, которое

select * from from cost where source = value and month = value group by day order by created_at asc

Это недопустимый оператор SQL, потому что вы выбираете все поля в таблице и ни один из них либо части в любом из любой функции совокупной или предложение group by.

Пожалуйста, проверьте это link для получения дополнительной информации о том, как написать правильную группу по предложению.

вот пример кода Rails, переведенного правильно в оператор sql, который содержит использование предложения 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)

Как вы можете видеть, у меня есть определенные все поля, которые мне нужно получить, и все эти поля являются либо частью агрегатной функции или используется группой по п.

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 

Вот nice tutorial

1

Если вы хотите использовать group, вы должны добавить своего рода вычисления или агрегирования функций на группах. Для выборки сгруппированных записей, попытайтесь получить сгруппированные идентификаторы, а затем вы можете получить только записи с заданными идентификаторами:

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)