我在pg生产模式下遇到此错误,但在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
答案 0 :(得分:42)
如果user_id
是 PRIMARY KEY ,则需要升级PostgreSQL;较新的版本将通过主键正确处理分组。
如果user_id
既不是唯一的 也不是 有关'estates'关系的主键,那么此查询没有多大意义,因为PostgreSQL没有办法知道要为estates
的每一列返回哪个值,其中多行共享相同的user_id
。您必须使用表达所需内容的聚合函数,例如min
,max
,avg
,string_agg
,array_agg
等,或添加列(s )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;
答案 1 :(得分:15)
我最近从MySQL迁移到PostgreSQL并遇到了同样的问题。仅供参考,我发现的最佳方法是使用DISTINCT ON,如本SO答案所示:
Elegant PostgreSQL Group by for Ruby on Rails / ActiveRecord
这将让您为所选列中的每个唯一值获取一条记录,该记录与其他查询条件匹配:
MyModel.where(:some_col => value).select("DISTINCT ON (unique_col) *")
我更喜欢DISTINCT ON,因为我仍然可以获取行中的所有其他列值。仅DISTINCT将仅返回该特定列的值。
答案 2 :(得分:6)
经常自己收到错误后,我意识到Rails(我使用的是rails 4)会自动添加一个'命令。在分组查询结束时。这通常会导致上述错误。因此,请确保在Rails查询结束时附加自己的.order(:group_by_column)。因此,你会有这样的事情:
@problems = Problem.select('problems.username, sum(problems.weight) as weight_sum').group('problems.username').order('problems.username')
答案 3 :(得分:3)
@myestate1 = Estate.where(:Mgmt => current_user.Company)
@myestate = @myestate1.select("DISTINCT(user_id)")
这就是我所做的。