【问题标题】:Programmatically composing INTERSECT and UNION queries with Arel or ActiveRecord使用 Arel 或 ActiveRecord 以编程方式组合 INTERSECT 和 UNION 查询
【发布时间】:2017-09-21 18:46:54
【问题描述】:

我需要在 Rails 5 中使用 Arel 或 ActiveRecord 编写查询,使用交集和联合。到目前为止,我发现的关于 SO 的每个答案通常似乎都涉及将 OP 给出的特定示例转换为另一种查询。这对我不起作用,因为这些查询是以编程方式组成的,到目前为止,最明智的做法是作为子查询,然后将其与 INTERSECT 和 UNION 连接。

& 相交并与| 联合完全有效,并且可以按照我的意愿进行操作,但是这两个都返回数组,因此会无缘无故地将巨大的巨大数据集带入内存。

MyModel.where(...).intersect(MyModel.where(...))

这种方法有效,但结果是Arel::Nodes::Intersect 而不是ActiveRecord::Relation,这没什么用。我尝试直接使用 Arel 构建这些,但对 Arel 缺乏文档感到沮丧。

是否有更 Railsy 的方式来实现这一点,并且仍然可以链接(即,仍然可以像 AR::Relation 一样延迟分页)?

【问题讨论】:

  • 请阅读“How to Ask”和链接页面,尤其是“How To s The Smart Way”。我们想知道你尝试了什么。以及为什么它不起作用。正如所写,您是在要求我们抛出一般性想法,而不是回答特定问题,这是 SO 方式。
  • 我不同意。我在问如何做一件非常具体的事情,使用 ActiveRecord 或 Arel 来表示同一张表上两个查询的交集。它们存储为单独的变量,因此不能像第一个答案那样真正链接起来。我基本上尝试了所有方法,最后直接使用 Arel 编写了一个更强大的解决方案。

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


【解决方案1】:

对于 INTERSECT,只需使用:

MyModel.where(...).where(...)

或者将它放在多行这样的语法会更好:

MyModel\
.where(...)
.where(...)

你也可以使用 where(nil),它不会影响关系。这在您以编程方式构建 where 条件(例如 where({a: a_val} if a_val.present?)时很有用。

对于 UNION,使用 Rails 5 or

MyModel.where(...).or(MyModel.where(...))

或使用多行语法:

MyModel\
.where(...)
.or(
MyModel\
.where(...)
)

【讨论】:

  • 这仅适用于同一张表中的交集,不适用于更复杂的查询。你知道如何执行使用 Arel 创建的路口吗?
猜你喜欢
  • 2016-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多