PostgreSQL - 必须出现在GROUP BY子句中或用于聚合函数

时间:2014-06-26 02:15:59

标签: ruby-on-rails postgresql activerecord heroku ruby-on-rails-4

此查询在本地工作,但由于某种原因在Heroku上不起作用。

2014-06-26T00:45:11.334388+00:00 app[web.1]: PG::GroupingError: ERROR:  column 
"conversations.updated_at" must appear in the GROUP BY clause or be used in an 
aggregate 
function

这是SQL。

Conversation.joins("INNER JOIN notifications ON 
notifications.conversation_id = conversations.id AND 
notifications.type IN ('Message') INNER JOIN receipts 
ON receipts.notification_id =  notifications.id WHERE 
notifications.type = 'Message' AND (receipts.receiver_id = #{a.id} 
AND receipts.receiver_type = 'Profile') AND conversations.id 
IN #{active_conversations_ids} ORDER BY conversations.updated_at DESC")

我尝试做了截然不同但它没有用,我尝试了group_by('conversation_id')

to_sql

SELECT "conversations".* FROM "conversations" INNER JOIN 
notifications ON notifications.conversation_id = conversations.id 
AND notifications.type IN ('Message') INNER JOIN receipts 
ON receipts.notification_id =  notifications.id WHERE
notifications.type = 'Message' AND (receipts.receiver_id = 104 
AND receipts.receiver_type = 'Profile') AND conversations.id 
IN (…) ORDER BY conversations.updated_at DESC"

2 个答案:

答案 0 :(得分:1)

如果您在本地计算机上运行应用程序,则可以在服务器窗口中看到SQL。

将连接保持在它们所属的位置是一种很好的做法。

Conversation.where('id' => active_conversations_ids).joins(
"INNER JOIN notifications ON notifications.conversation_id = conversations.id 
  AND notifications.type IN ('Message') 
INNER JOIN receipts ON receipts.notification_id = notifications.id 
  AND (receipts.receiver_id = #{a.id} AND receipts.receiver_type = 'Profile')"
).order('updated_at')

为了更好的可读性,您可以使用符号通知。

Conversation
.find_all_by_id(active_conversations_ids)
.joins(:notifications, :receipts).where({   
    notifications: { type: 'Message' }, 
    receipts: { receiver_id: a.id, receiver_type: 'Profile'}
})
.order('updated_at')

我的最终建议是谷歌指定范围。

http://zachholman.com/2010/01/simplifying-rails-controllers-with-named_scopes/

答案 1 :(得分:0)

就像添加

一样简单
GROUP BY conversations.id

最终看起来像

Conversation.joins("INNER JOIN notifications ON 
notifications.conversation_id = conversations.id AND 
notifications.type IN ('Message') INNER JOIN receipts ON 
receipts.notification_id = notifications.id WHERE 
notifications.type = 'Message' AND (receipts.receiver_id = #{self.id}) AND 
conversations.id IN #{active_conversation_ids} GROUP BY 
conversations.id ORDER BY conversations.updated_at DESC")
.select('conversations.id, conversations.updated_at')