Rails 3,ActiveRecord,PostgreSQL - “。uniq”命令不起作用?

时间:2012-03-18 13:42:52

标签: database ruby-on-rails-3 postgresql activerecord uniq

我有以下查询:

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15).uniq

并给我错误

PG::Error: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...s"."user_id" WHERE (articles.user_id != 1) ORDER BY Random() L...

当我更新原始查询

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15)#.uniq

所以错误消失了......在MySQL .uniq 中,在PostgreSQL中没有。存在任何替代方案?

4 个答案:

答案 0 :(得分:30)

错误表明for SELECT DISTINCT, ORDER BY expressions must appear in select list。 因此,您必须明确选择要订购的子句。

这是一个例子,它类似于你的情况,但略有概括。

Article.select('articles.*, RANDOM()')
       .joins(:users)
       .where(:column => 'whatever')
       .order('Random()')
       .uniq
       .limit(15)

因此,请使用ORDER BY明确包含您的RANDOM()子句(本例中为.select())。如上所示,为了使您的查询返回Article属性,您还必须明确选择它们。

我希望这会有所帮助;祝你好运

答案 1 :(得分:2)

只是为了通过更多示例丰富线程,如果您在查询中有嵌套关系,可以尝试使用以下语句。

Person.find(params[:id]).cars.select('cars.*, lower(cars.name)').order("lower(cars.name) ASC")

在给出的示例中,您要求按照车型名称(奥迪,法拉利,保时捷)订购给定人员的所有车辆

我不认为这是一种更好的方法,但可能有助于解决在对象和集合中思考的这种情况,而不是关系(数据库)方式。

谢谢!

答案 2 :(得分:1)

我假设.uniq方法被转换为SQL上的DISTINCT子句。 PostgreSQL很挑剔(比MySQL更挑剔) - 使用DISTINCT时,选择列表中的所有字段都必须出现在ORDER_BY(和GROUP_BY)子句中。

有点不清楚你要做什么(随机排序?)。除了发布完整的SQL发送,如果您可以解释您的目标,这可能有助于找到替代方案。

答案 3 :(得分:0)

我刚刚将我的100%工作和测试应用程序从3.1.1升级到3.2.7,现在有了相同的PG ::错误。

我正在使用Cancan ......

@users = User.accessible_by(current_ability).order('lname asc').uniq

删除.uniq可以解决问题,无论如何都不需要这个简单的查询。

仍在查看3.1.1和3.2.7之间的变化说明,看看是什么导致了这种变化。