在SQLite(开发)中我没有任何错误,但在Postgres的生产中我收到以下错误。我真的不明白这个错误。
PG::Error: ERROR: column "commits.updated_at" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: ...mmits"."user_id" = 1 GROUP BY mission_id ORDER BY updated_at...
^
: SELECT COUNT(*) AS count_all, mission_id AS mission_id FROM "commits" WHERE "commits"."user_id" = 1 GROUP BY mission_id ORDER BY updated_at DESC
我的控制器方法:
def show
@user = User.find(params[:id])
@commits = @user.commits.order("updated_at DESC").page(params[:page]).per(25)
@missions_commits = @commits.group("mission_id").count.length
end
更新
所以我深入研究了这个PostgreSQL特有的烦恼,我很惊讶Ruby on Rails指南中没有提到这个异常。
我正在使用psql (PostgreSQL) 9.1.11
因此,根据我的理解,我需要指定在使用GROUP_BY
子句时应该使用哪个列。我认为使用SELECT
会有所帮助,如果您需要SELECT
很多列,这可能很烦人。
无论如何,当我查看错误时,每次光标都指向updated_at
。在SQL查询中,rails始终为ORDER BY updated_at
。所以我尝试了这个可怕的问题:
@commits.group("mission_id, date(updated_at)")
.select("date(updated_at), count(mission_id)")
.having("count(mission_id) > 0")
.order("count(mission_id)").length
它给了我以下SQL
SELECT date(updated_at), count(mission_id)
FROM "commits"
WHERE "commits"."user_id" = 1
GROUP BY mission_id, date(updated_at)
HAVING count(mission_id) > 0
ORDER BY updated_at DESC, count(mission_id)
LIMIT 25 OFFSET 0
错误是一样的。
注意,无论ORDER BY updated_at是什么,即使我想按其他方式订购。
此外,我不希望仅通过mission_id对updated_at进行分组。
这个PostgreSQL错误只是误导而且解决它的解释很少。我已经尝试了stackoverflow侧边栏中的许多公式,没有任何作用,总是出现相同的错误。
更新2:
所以我让它工作,但由于自动updated_at
,它需要对ORDER BY updated_at
进行分组。我如何仅按mission_id
计算?
@missions_commits = @commits.group("mission_id, updated_at").count("mission_id").size
答案 0 :(得分:1)
请在此处查看PostgreSQL GROUP BY的文档:
http://www.postgresql.org/docs/9.3/interactive/sql-select.html#SQL-GROUPBY
基本上,与Sqlite(和MySQL)不同,postgres要求选择或订购的任何列必须出现在聚合函数或group by子句中。
如果你仔细想想,你会发现这实际上是有道理的。 Sqlite / MySQL在引擎盖下作弊并默默地丢弃这些字段(不确定技术上会发生什么)。
或者如果你按照字段进行分组,可以考虑另一种方式,订购它的重点是什么?除非你在有序字段上也有一个聚合函数,这怎么会有意义呢?
答案 1 :(得分:1)
我是客人,你想要显示与提交有关的不同任务的一般数量,无论如何它不会是页面上的数字。
试试这个:
@commits = @user.commits.order("updated_at DESC").page(params[:page]).per(25)
@missions_commits = @user.commits.distinct.count(:mission_id)
但是,如果您想在页面上获取不同任务的数量,我认为它应该是:
@missions_commits = @commits.collect(&:mission_id).uniq.count
<强>更新强>
在Rails 3中,distinct
不存在,但应以这种方式使用纯SQL计数:
@missions_commits = @user.commits.count(:mission_id, distinct: true)