gpt4 book ai didi

ruby-on-rails - 使用 Arel (Rails 5) 构建三重 UNION 查询

转载 作者:行者123 更新时间:2023-12-05 05:07:15 27 4
gpt4 key购买 nike

用户有_许多任务

我正在尝试创建一个 3 select UNION:

Task.from("(#{select1.to_sql} UNION #{select2.to_sql} UNION #{select3.to_sql}) AS tasks")

但是有了 Arel。

我可以轻松地使用 Arel 进行 2 次选择的 UNION 查询:

tasks_t = Task.arel_table
select1 = tasks_t.project('id').where(tasks_t[:id].eq(1)) # SELECT id FROM tasks WHERE tasks.id = 1
select2 = Task.joins(:user).select(:id).where(users: {id: 15}).arel # SELECT "tasks".id FROM "tasks" INNER JOIN "users" ON "users"."id" = "tasks"."user_id" WHERE "users"."id" = 15
union = select1.union(select2) # SELECT * FROM users WHERE users.id = 1 UNION SELECT * FROM users WHERE users.id = 2

union_with_table_alias = tasks_t.create_table_alias(union, tasks_t.name)
Task.from(union_with_table_alias)
# SELECT "tasks".* FROM ( SELECT id FROM "tasks" WHERE "tasks"."id" = 1 UNION SELECT "tasks"."id" FROM "tasks" INNER JOIN "users" ON "users"."id" = "tasks"."user_id" WHERE "users"."id" = $1 ) "tasks" [["id", 15]]

#=> Task::ActiveRecord_Relation [#<Task: id: 1>, #<Task: id: 2>]

如何使用三重联合选择来实现?

select3 = tasks_t.project('id').where(tasks_t[:id].eq(3)) # SELECT id FROM tasks WHERE tasks.id = 3

类似于:

triple_union = select1.union(select2).union(select3)
triple_union_with_table_alias = tasks_t.create_table_alias(triple_union, tasks_t.name)
Task.from(triple_union_with_table_alias)

应该大致翻译成

Task.from("(#{select1.to_sql} UNION #{select2.to_sql} UNION #{select3.to_sql}) AS tasks")

请注意,上面的行也失败了:由 PG::ProtocolViolation 引起:错误:绑定(bind)消息提供 0 个参数,但准备语句“”需要 1 个

总结一下:如何使用 Arel 构建三重 UNION 查询? 选择 1 UNION 选择 2 UNION 选择 3

谢谢

Ruby 2.5.3 Rails 5.2.4 Arel 9.0.0

最佳答案

您不能在 Arel::Nodes::Union 中调用 union,因为在方法定义中,两个对象的 ast 都是叫。 union 操作的结果不响应 ast:

def union operation, other = nil
if other
node_class = Nodes.const_get("Union#{operation.to_s.capitalize}")
else
other = operation
node_class = Nodes::Union
end

node_class.new self.ast, other.ast
end

您可以做的是手动调用 Arel::Nodes::Union,将联合的结果作为这些参数中的任何一个传递:

Arel::Nodes::Union.new(Arel::Nodes::Union.new(select1, select2), select3)

关于ruby-on-rails - 使用 Arel (Rails 5) 构建三重 UNION 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59294114/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com