【发布时间】:2023-01-20 03:46:29
【问题描述】:
我有两个表(A 和 B)和一个相对复杂的 Active::Record::Relation,它从这两个表的连接中选择。查询使用ActiveRecord::Base.connection.exec_query joined.to_sql 正确执行,也就是说,它从每个表中打印出我想要的列(A.id、A.title、b.num)。
然后我想将这个“连接”表作为 Arel::Table 传递,以用于程序的其余部分。但是,当我运行 at_j=joined.arel_table 时,Arel 表是从原始数据库 A 创建的,而不是从“连接”查询产生的结果创建的,即我从 A 获取所有列(不仅是选定的列),而且没有来自 B 的列
我意识到第一步是从一个已经过滤的表中创建一个 arel 表,即如果 A 有列 id、title、c1、c2、c3...我希望能够做到:
filtered=A.select(:id,:title)
at_f=filtered.arel_table
并且只在 at_f 中获取 id 和 title,但事实并非如此,我还获取了 c1、c2、c3....
我知道我能做到
at_f=A.arel_table.project(:id,:title)
但这会输出一个 Arel::SelectManager,我需要传递一个 Arel::Table(这是我无法控制的)。
我也不想在 Arel 中构建查询,因为我需要修改作为输入给出的表 A,我可以使用 _selct! 和 joins! 来完成。
有没有办法做到这一点?我想过使用类似的东西
at_f=Arel::Table.new(filtered.to_sql)
但这失败了,不出所料......
在此先感谢您的帮助。
.....................................
如果这有用,这就是我获得“加入”活动记录关系的方式:
A._select!(:id,:title,'b.num')
bf=B.where(c1: 'x',c2: 'y')
num=bf.select('id_2 AS A_id, COUNT(id_2) AS num').group(:id_2)
A.joins!("LEFT OUTER JOIN (#{num.to_sql}) b ON A.id = b.A_id")
这是它生成的查询:
# A.to_sql:
SELECT `A`.`id`, `A`.`title`, `b`.`num`
FROM `A` LEFT OUTER JOIN
(SELECT id_2 AS A_id, COUNT(id_2) AS num
FROM `B` WHERE `B`.`c1` = 'x' AND `B`.`c2` = 'y'
GROUP BY `B`.`id_2`) b
ON A.id = b.A_id
【问题讨论】:
-
我非常乐意提供帮助(我喜欢 arel 问题)但是我对这里想要的结果有点不清楚。您尝试构建的查询是什么?您希望返回哪些对象?您还需要解释这部分“我需要传递一个 Arel::Table(这是我无法控制的)”因为你无法从中得到
Arel::Table,但如果我理解上下文,我们可以让你非常接近并且功能相当。
标签: sql ruby-on-rails ruby activerecord arel