PG :: InvalidColumnReference:错误:对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中

时间:2017-03-16 22:58:46

标签: ruby-on-rails postgresql activerecord arel

我有一长串的关联,连接,排序等,最终从我的一个导轨模型中选择。在一天结束时,我需要结果是独特的和分类的。我不关心SELECT语句中使用哪些列,ORDER BY中出现的内容等等(这些都根据用户选择的过滤选项而改变),我只关心顶级模型/表在查询中是唯一的(基于id)。

对于后台,widgets是主要表格,我们正在加入widget_steps,这是在Rails 3中(公司正在努力尽快升级,但这就是他们所做的&#39} ;现在再次坚持)

以下是正在生成的查询和错误:

PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...completed_at" IS NULL)) ORDER BY sequential DESC, widget_s...
                                                             ^
: SELECT  DISTINCT "widgets".* FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0
Completed 500 Internal Server Error in 52.3ms

ActiveRecord::StatementInvalid - PG::InvalidColumnReference: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...completed_at" IS NULL)) ORDER BY sequential DESC, widget_s...
                                                             ^
: SELECT  DISTINCT "widgets".* FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0:

为什么这是一件事? postgres认为这是多么含糊不清?为什么像这样的查询在MySQL中总能正常工作,但会使postgres窒息。

我试过了:

  1. 在链的末尾指定.select([everything mentioned in the order by]).uniq
  2. 在链的末尾指定.uniq而不进行自定义选择
  3. 编写一些自定义AREL以尝试将所有这些嵌入到子查询中,然后在此之外执行.uniq或.order(无法使其正常工作)
  4. 在postgres之外做.uniq(这会因为分页而中断...你最终会得到一些页面上只有1或2个项目,因为重复删除了)
  5. 哭闹

3 个答案:

答案 0 :(得分:2)

您需要将Int添加到所选列的列表中:

widget_steps.name

这不应该改变查询的逻辑,并且可以正常工作。

在Rails中,您可以使用SELECT DISTINCT "widgets".*, "widget_steps.name" FROM "widgets" INNER JOIN "widget_steps" ON "widget_steps"."widget_id" = "widgets"."id" INNER JOIN "widget_steps" "active_steps_widgets" ON "active_steps_widgets"."id" = "widgets"."active_widget_step_id" WHERE "widgets"."account_id" = 1 AND "widgets"."completed_at" IS NULL AND (("widgets"."sequential" = 't' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."id" = "widgets"."active_widget_step_id" AND "widget_steps"."completed_at" IS NULL) OR ("widgets"."sequential" = 'f' AND "widget_steps"."assigned_to" = 5 AND "widget_steps"."completed_at" IS NULL)) ORDER BY sequential DESC, widget_steps.name ASC LIMIT 10 OFFSET 0 方法设置所选列的列表:

select

希望这会有所帮助。

答案 1 :(得分:0)

建议:

您可以在Widget类中添加has_many :steps,然后使用Widget.includes(:steps)执行带有Order子句的查询,该子句按widget_steps列进行排序

答案 2 :(得分:0)

在某些情况下(例如has_and_belongs_to_many类型关系)可能会发生此错误的另一个选项是取消范围限制:

#Code
data <- data[!data$id %in% id_to_remove,]

这应该让您完成所有这些操作

class Resource < ApplicationRecord
  has_and_belongs_to_many :things
  scope :with_blue_things, -> { joins(:things).where(:things => {:color => :blue}).unscope(:order).distinct }