【发布时间】:2019-07-03 21:21:53
【问题描述】:
我有类似的东西:
(Model.where(status: :active).to_a << Model.last).uniq
我正在寻找一种方法来在一个查询中实现它。这可能吗?
【问题讨论】:
-
在 SQL 中,您通常会使用 UNION
标签: mysql sql ruby-on-rails ruby
我有类似的东西:
(Model.where(status: :active).to_a << Model.last).uniq
我正在寻找一种方法来在一个查询中实现它。这可能吗?
【问题讨论】:
标签: mysql sql ruby-on-rails ruby
您可以使用纯 SQL 构造查询,然后使用ActiveRecord#find_by_sql 获取 ActiveRecord 对象数组:
query = <<-SQL
SELECT * FROM subscriptions
WHERE
status = 'active' OR
id = (SELECT max(id) FROM subscriptions)
SQL
Subscription.find_by_sql(query) #=> [ array of subscriptions]
如果您需要 ActiveRecord::Relation 实例,请使用 ActiveRecord#from 方法。它允许将普通 SQL 传递到 FROM 语句中。由于#from 返回关系,您可以使用所有 Active Record 方法进行查询
Subscription.from(query).where('created_at > ?', Time.zone.now)
它像这样构建单个查询:
SELECT * FROM (
SELECT * FROM subscriptions
WHERE
status = 'active' OR
id = (SELECT max(id) FROM subscriptions)
) WHERE created_at > '2019-01-01 00:00'
【讨论】:
我认为您不能使用单个查询,也许您可以使用嵌套子查询进行查询,但仅使用 ActiveRecord(也许使用 Arel)并不能那么容易。
就个人而言,我会使用 2 个 ActiveRecord 查询,一个是获取 las 记录的 id,然后是实际查询:
last_id = Model.last.id
records = Model.where(status: active).or(Model.where(id: last_id))
您将有 2 个查询,但第一个查询会非常贬值,而第二个查询比将所有结果转换为数组并执行 uniq 快得多。
【讨论】: