【问题标题】:ActiveRecord query is forcing ORDER BY after DISTINCTActiveRecord 查询在 DISTINCT 之后强制 ORDER BY
【发布时间】:2016-11-13 06:51:48
【问题描述】:

我正在使用这个查询:

Post.where("created_at >= ? AND created_at <= ?", 1.month.ago.beginning_of_month , 1.month.ago.end_of_month)
    .select('DISTINCT user_id')

返回 40 个元素。但是,我希望从这个查询中得到一个数组,并且能够用.each 遍历这个数组。问题是当我尝试在查询结果上使用.each 时,我得到了这个:

ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY 表达式必须出现在选择列表中 第 1 行:...ted_at = '2016-05-31 22:00:00.000000' AND created_at

似乎此查询在created_at 上强制使用ORDER BY,并使其中断,因为查询中没有 order_by。

为了避免这个问题,我正在使用:

Post.where("created_at >= ? AND created_at <= ?", 1.month.ago.beginning_of_month , 1.month.ago.end_of_month)
    .map{|p| p.user_id}.uniq

效率较低。

知道为什么我会收到此错误吗?

【问题讨论】:

    标签: sql ruby-on-rails postgresql activerecord rails-activerecord


    【解决方案1】:

    尝试以下方法:

    Post.where(created_at: (1.month.ago.beginning_of_month)..1.month.ago.end_of_month)
        .distinct.reorder(nil).pluck(:user_id)
    

    正如 cmets 中所述,这是由于 default_scope:

    default_scope {order('created_at DESC')}
    

    【讨论】:

    • 同样的错误:SELECT DISTINCT "posts"."user_id" FROM "posts" WHERE (created_at >= '2016-05-31 22:00:00.000000' AND created_at
    • 仍然是一个错误:ActiveRecord::StatementInvalid: PG::InvalidColumnReference: 错误:对于 SELECT DISTINCT,ORDER BY 表达式必须出现在选择列表第 1 行中: ...ted_at = '2016-05-31 22:00:00.000000' AND created_at
    • 如果我将 .pluck(:user_id) 更改为 .pluck(:user_id, :created_at),它会起作用,但这不是我想要的结果,因为我需要迭代结果以仅提取user_id
    • 什么是强制命令?
    • 好吧,太棒了,所以您的答案有效,您对 default_scope 的假设确实是问题所在。非常感谢,你帮了很多忙!
    猜你喜欢
    • 2013-01-25
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多