Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.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 PG::GROUPBY子句中出现错误_Ruby On Rails_Postgresql - Fatal编程技术网

Ruby on rails PG::GROUPBY子句中出现错误

Ruby on rails PG::GROUPBY子句中出现错误,ruby-on-rails,postgresql,Ruby On Rails,Postgresql,我想不出更好的方法来重构下面的代码(请参阅),尽管我知道这很难看。但是,它抛出了一个Postgres错误(不是SQLite): 查询本身是: SELECT "articles".* FROM "articles" WHERE "articles"."user_id" = 1 GROUP BY publication 它来自以下视图代码: =@user.articles.group(:publication).map do |p| =p.publication =@user.art

我想不出更好的方法来重构下面的代码(请参阅),尽管我知道这很难看。但是,它抛出了一个Postgres错误(不是SQLite):

查询本身是:

SELECT "articles".* 
FROM "articles" 
WHERE "articles"."user_id" = 1 
GROUP BY publication
它来自以下视图代码:

=@user.articles.group(:publication).map do |p|
  =p.publication
  =@user.articles.where("publication = ?", p.publication).sum(:twitter_count)
  =@user.articles.where("publication = ?", p.publication).sum(:facebook_count)
  =@user.articles.where("publication = ?", p.publication).sum(:linkedin_count)
在SQLite中,这提供了输出(例如)NYT121814 BBC 454647 CNN755478,这正是我所需要的


如何改进代码以删除此错误?

使用
分组依据
时,不能
选择既不属于
分组依据
的字段,也不能在聚合函数中使用。这是由SQL标准指定的,尽管有些数据库仍然选择执行此类查询。因为没有一种正确的方法来执行这样的查询,所以他们倾向于选择他们找到的第一行并返回它,所以结果会有不可预测的变化

看起来你想说:

“对于每一份出版物,请给我该出版物的twitter、facebook和linkedin的总数”

如果是这样,你可以写:

SELECT publication,
       sum(twitter_count) AS twitter_sum,
       sum(linkedin_count) AS linkedin_sum,
       sum(facebook_count) AS facebook_sum
FROM "articles" 
WHERE "articles"."user_id" = 1 
GROUP BY publication;

将其转换为ActiveRecord/Rails。。。由你决定,我不用它。看起来这和你想写的差不多,但ActiveRecord似乎弄糟了,可能是想在本地执行求和。

Craig的回答很好地解释了这个问题。默认情况下,活动记录将
选择*
,但您可以轻松覆盖它:

@user.articles.select("publication, sum(twitter_count) as twitter_count").group(:publication).each do |row|
  p row.publication # "BBC"
  p row.twitter_count # 45
end

PostgreSQL版本?较旧的PostgreSQL版本没有意识到,当您按照
主键对
进行分组时,您是按照所有列进行隐式分组的。如果
publication
不是主键,那么生成的SQL是完全错误的,没有任何意义。它是在Herokand上运行的PG版本:9.1.9,
publication
是主键吗?如果不是这样,生成的代码是毫无意义的。是的,对不起,
publication
不是主键,
id
是。但我认为按其他字段分组是可以的?是的,但正如错误消息明确指出的那样,您必须按字段分组,或者在聚合表达式中使用它。所以您不能只选择表。*
。当存在多种可能性时,PostgreSQL如何知道为一行返回哪个结果?随便挑一个?它不会那样做的。其他一些数据库违反了标准,执行了不正确的查询,在PostgreSQL拒绝执行的情况下,会产生不可预测/定义不清的结果。谢谢-我对这一解释投了赞成票。但我看不出是什么导致我的Rails代码以这种方式运行,而这正是我真正需要修复的地方。不过,我会尝试在本地执行,好主意。@Nick ugh,不;我怀疑ActiveRecord试图获取数据,然后在本地进行自己的过滤,但我认为这不是一个特别好的主意。如果ActiveRecord搞错了,为什么不直接使用原生SQL呢?实际上,你不能直接写:=p.publication=sum(p.twitter\u count)=sum(p.facebook\u count)=sum(p.linkedin\u count)?(我不说ActiveRecord,所以这可能是胡言乱语;重点是我怀疑WHERE子句混淆了它,因为WHERE与GROUP BY一起没有意义)不幸的是,没有-当我这样做时,它抛出了一个未定义的方法错误(以及其他几个排列)。虽然它会更干净。是的,这个代码可以工作。我不得不在那里添加更多的选择(“sum(facebook_count)作为facebook_count,sum(linkedin_count)作为linkedin_count”),但它返回了我需要的所有数据,比我的努力要好。谢谢,谢谢。因为我不会说ActiveRecord,所以我永远也不会知道。
@user.articles.select("publication, sum(twitter_count) as twitter_count").group(:publication).each do |row|
  p row.publication # "BBC"
  p row.twitter_count # 45
end