Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 带有PostgreSQL:GroupBy的Rails 3.1必须在聚合函数中使用_Ruby On Rails_Ruby_Postgresql - Fatal编程技术网

Ruby on rails 带有PostgreSQL:GroupBy的Rails 3.1必须在聚合函数中使用

Ruby on rails 带有PostgreSQL:GroupBy的Rails 3.1必须在聚合函数中使用,ruby-on-rails,ruby,postgresql,Ruby On Rails,Ruby,Postgresql,我正在尝试加载最新的10个艺术作品,这些作品按用户id分组,并按created_at订购。这在SqlLite和MySQL中运行良好,但在我的新PostgreSQL数据库中出现了一个错误 Art.all(:order => "created_at desc", :limit => 10, :group => "user_id") ActiveRecord错误: Art Load (18.4ms) SELECT "arts".* FROM "arts" GROUP BY use

我正在尝试加载最新的10个艺术作品,这些作品按用户id分组,并按created_at订购。这在SqlLite和MySQL中运行良好,但在我的新PostgreSQL数据库中出现了一个错误

Art.all(:order => "created_at desc", :limit => 10, :group => "user_id")
ActiveRecord错误:

Art Load (18.4ms)  SELECT "arts".* FROM "arts" GROUP BY user_id ORDER BY created_at desc LIMIT 10
ActiveRecord::StatementInvalid: PGError: ERROR:  column "arts.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT  "arts".* FROM "arts"  GROUP BY user_id ORDER BY crea...
有什么想法吗?

看看这篇文章


PostGres实际上是在遵循SQL标准,而sqlite和mysql则打破了这一标准。

看看这个问题-。Postgres不允许在不在group by子句中的select语句中列出列

表达式生成的sql不是有效的查询,您正在按
user\u id
进行分组,并在此基础上选择许多其他字段,但没有告诉DB应该如何聚合其他文件。例如,如果您的数据如下所示:

a  | b
---|---
1  | 1
1  | 2
2  | 3
现在,当您要求db按
a
分组并返回b时,它不知道如何聚合值
1,2
。您需要告诉它是否需要选择最小值、最大值、平均值、总和或其他。就在我写答案的时候,有两个答案可以更好地解释这一切

不过,在您的用例中,我认为您不希望在db级别上使用GROUPBY。由于只有10门艺术,您可以在应用程序中对它们进行分组。不过,千万不要将此方法用于成千上万的艺术作品:

 arts = Art.all(:order => "created_at desc", :limit => 10)
 grouped_arts = arts.group_by {|art| art.user_id}
 # now you have a hash with following structure in grouped_arts
 # { 
 #    user_id1 => [art1, art4],
 #    user_id2 => [art3],
 #    user_id3 => [art5],
 #    ....
 # }
编辑:选择最新的艺术,但每个用户只能选择一种艺术

只是让您了解一下sql(由于我的系统上没有安装RDBMS,所以没有对其进行测试)

这个解决方案基于一个实际的假设,即同一用户的两个艺术作品不可能有相同的最高创作水平,但如果您导入或以编程方式创建大量艺术作品,则很可能是错误的。如果假设不成立,那么sql可能会变得更加复杂

编辑:尝试将查询更改为Arel:

Art.where("(arts.user_id, arts.created_at) IN 
             (SELECT user_id, MAX(created_at) FROM arts
                GROUP BY user_id
                ORDER BY MAX(created_at) DESC
                LIMIT 10)").
    order("created_at DESC").
    page(params[:page]).
    per(params[:per])

您需要选择所需的特定列

艺术选择(:用户id).组(:用户id).限制(10)

例如,当您尝试在查询中选择标题时,它将引发错误

艺术选择(:用户id,:标题)。组(:用户id)。限制(10)

列“arts.title”必须出现在GROUP BY子句中,或在聚合函数中使用

这是因为当您尝试按用户id分组时,查询不知道如何处理组中的标题,因为组包含多个标题

因此,例外情况已经提到您需要按分组出现

艺术选择(:用户id,:标题)。组(:用户id,:标题)。限制(10)

或在聚合函数中使用

艺术选择(“用户id,数组集合(标题)作为标题”)。组(:用户id)。限制(10)


我有6000条记录,所以这可能会成为性能问题。我看到您有两条用户_id1的记录。我正在尝试加载最新的10件艺术品-只有一个公关用户。这不会是一个性能问题,直到你有一个限制条款10,但第二个问题仍然存在。我想可能会有原始sql来处理您想要的内容,但将其转换为Arel可能会很困难。更新了答案,但不确定其语法是否正确。让我知道这是否有效。你的例子有效。我有很多麻烦,让这个发挥与分页。这可以通过活动记录完成吗?这样您就可以调用.page(params[:page]).per(20)等方法。尝试将其转换为arel语法,但此查询很难转换。
Art.where("(arts.user_id, arts.created_at) IN 
             (SELECT user_id, MAX(created_at) FROM arts
                GROUP BY user_id
                ORDER BY MAX(created_at) DESC
                LIMIT 10)").
    order("created_at DESC").
    page(params[:page]).
    per(params[:per])