PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
我有一长串关联、连接、排序依据等,最终 select 来自我的一个 rails 模型。在一天结束时,我需要结果是唯一的和排序的。我不关心 SELECT 语句中使用了哪些列,ORDER BY 中出现了什么,等等(这些都根据用户 selected 的过滤选项而改变),我只关心查询中的顶级 model/table 是唯一的(基于 id)。
对于背景,widgets
是主要的 table,我们正在加入 widget_steps
,这是在 Rails 3(公司正在尝试尽快升级但这就是他们目前所坚持的)
这是正在生成的查询和错误:
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 窒息。
我试过:
- 在链的末尾指定
.select([everything mentioned in the order by]).uniq
- 在链的末尾指定
.uniq
而不进行自定义 select
- 编写一些自定义 AREL 以尝试将所有这些嵌入到子查询中,然后在此之外执行 .uniq 或 .order(无法正常工作)
- 在 postgres 之外执行 .uniq(这会因为分页而中断......由于重复项被删除,您最终可能会得到一些只有 1 或 2 个项目的页面)
- 哭泣
您需要将 widget_steps.name
添加到所选列的列表中:
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
这不会改变您的查询逻辑,并且可以正常工作。
在 Rails 中,您可以使用 select
方法来设置所选列的列表:
Widget.select('"widgets".*, "widget_steps.name"')
希望这会有所帮助。
建议:
您可以在 Widget class 中添加 has_many :steps
,并使用 Widget.includes(:steps) 执行一个查询,其中包含按 widget_steps 列排序的 Order 子句
另一个可能适用于某些情况(例如 has_and_belongs_to_many 类型关系)的错误选项是取消范围顺序:
class Resource < ApplicationRecord
has_and_belongs_to_many :things
scope :with_blue_things, -> { joins(:things).where(:things => {:color => :blue}).unscope(:order).distinct }
这应该让你做所有这些
Resource.with_blue_things
Resource.with_blue_things.count
Resource.with_blue_things.order(:name).count
我有一长串关联、连接、排序依据等,最终 select 来自我的一个 rails 模型。在一天结束时,我需要结果是唯一的和排序的。我不关心 SELECT 语句中使用了哪些列,ORDER BY 中出现了什么,等等(这些都根据用户 selected 的过滤选项而改变),我只关心查询中的顶级 model/table 是唯一的(基于 id)。
对于背景,widgets
是主要的 table,我们正在加入 widget_steps
,这是在 Rails 3(公司正在尝试尽快升级但这就是他们目前所坚持的)
这是正在生成的查询和错误:
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 窒息。
我试过:
- 在链的末尾指定
.select([everything mentioned in the order by]).uniq
- 在链的末尾指定
.uniq
而不进行自定义 select - 编写一些自定义 AREL 以尝试将所有这些嵌入到子查询中,然后在此之外执行 .uniq 或 .order(无法正常工作)
- 在 postgres 之外执行 .uniq(这会因为分页而中断......由于重复项被删除,您最终可能会得到一些只有 1 或 2 个项目的页面)
- 哭泣
您需要将 widget_steps.name
添加到所选列的列表中:
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
这不会改变您的查询逻辑,并且可以正常工作。
在 Rails 中,您可以使用 select
方法来设置所选列的列表:
Widget.select('"widgets".*, "widget_steps.name"')
希望这会有所帮助。
建议:
您可以在 Widget class 中添加 has_many :steps
,并使用 Widget.includes(:steps) 执行一个查询,其中包含按 widget_steps 列排序的 Order 子句
另一个可能适用于某些情况(例如 has_and_belongs_to_many 类型关系)的错误选项是取消范围顺序:
class Resource < ApplicationRecord
has_and_belongs_to_many :things
scope :with_blue_things, -> { joins(:things).where(:things => {:color => :blue}).unscope(:order).distinct }
这应该让你做所有这些
Resource.with_blue_things
Resource.with_blue_things.count
Resource.with_blue_things.order(:name).count