PostgreSQL - должен присутствовать в предложении GROUP BY или использоваться в статистической функции.
Я получаю эту ошибку в режиме pg production, но она нормально работает в режиме разработки sqlite3.
ActiveRecord::StatementInvalid in ManagementController#index
PG::Error: ERROR: column "estates.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = ...
^
: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = 'Mazzey' GROUP BY user_id
@myestate = Estate.where(:Mgmt => current_user.Company).group(:user_id).all
4 ответа
@myestate1 = Estate.where(:Mgmt => current_user.Company)
@myestate = @myestate1.select("DISTINCT(user_id)")
это то, что я сделал
Если user_id
это ПЕРВИЧНЫЙ КЛЮЧ, тогда вам нужно обновить PostgreSQL; более новые версии будут правильно обрабатывать группировку по первичному ключу.
Если user_id
не является ни уникальным, ни первичным ключом для рассматриваемого отношения 'estates', тогда этот запрос не имеет особого смысла, так как PostgreSQL не может узнать, какое значение вернуть для каждого столбца estates
где несколько строк разделяют одно и то же user_id
, Вы должны использовать агрегатную функцию, которая выражает то, что вы хотите, например, min
, max
, avg
, string_agg
, array_agg
и т. д. или добавьте интересующие вас столбцы в GROUP BY
,
Вы также можете перефразировать запрос, чтобы использовать DISTINCT ON
и ORDER BY
если вы действительно хотите выбрать несколько произвольную строку, хотя я действительно сомневаюсь, что это можно выразить через ActiveRecord.
Некоторые базы данных, включая SQLite и MySQL, просто выбирают произвольную строку. Команда PostgreSQL считает, что это неправильно и небезопасно, поэтому PostgreSQL следует стандарту SQL и считает такие запросы ошибочными.
Если у вас есть:
col1 col2
fred 42
bob 9
fred 44
fred 99
и вы делаете:
SELECT col1, col2 FROM mytable GROUP BY col1;
тогда очевидно, что вы должны получить строку:
bob 9
но как насчет результата для fred
? Не существует единого правильного ответа, поэтому база данных откажется выполнять такие небезопасные запросы. Если бы вы хотели величайшего col2
для любого col1
вы бы использовали max
агрегатный:
SELECT col1, max(col2) AS max_col2 FROM mytable GROUP BY col1;
Недавно я перешел с MySQL на PostgreSQL и столкнулся с той же проблемой. Просто для справки, лучший подход, который я нашел, это использовать DISTINCT ON, как предложено в этом ответе SO:
Элегантная группа PostgreSQL для Ruby on Rails / ActiveRecord
Это позволит вам получить одну запись для каждого уникального значения в выбранном вами столбце, которое соответствует другим условиям запроса:
MyModel.where(:some_col => value).select("DISTINCT ON (unique_col) *")
Я предпочитаю DISTINCT ON, потому что я все еще могу получить все другие значения столбца в строке. Только DISTINCT будет возвращать только значение этого конкретного столбца.
После частого получения ошибки я понял, что Rails (я использую rails 4) автоматически добавляет 'order by id' в конце вашего запроса на группировку. Это часто приводит к ошибке выше. Поэтому убедитесь, что вы добавляете свой собственный.order(:group_by_column) в конце вашего запроса Rails. Следовательно у вас будет что-то вроде этого:
@problems = Problem.select('problems.username, sum(problems.weight) as weight_sum').group('problems.username').order('problems.username')