【问题标题】:Query for all records with a status plus the last one (no matter what status) in one query在一次查询中查询具有状态加上最后一条(无论是什么状态)的所有记录
【发布时间】:2019-07-03 21:21:53
【问题描述】:

我有类似的东西:

(Model.where(status: :active).to_a << Model.last).uniq

我正在寻找一种方法来在一个查询中实现它。这可能吗?

【问题讨论】:

  • 在 SQL 中,您通常会使用 UNION

标签: mysql sql ruby-on-rails ruby


【解决方案1】:

您可以使用纯 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'

【讨论】:

    【解决方案2】:

    我认为您不能使用单个查询,也许您可​​以使用嵌套子查询进行查询,但仅使用 ActiveRecord(也许使用 Arel)并不能那么容易。

    就个人而言,我会使用 2 个 ActiveRecord 查询,一个是获取 las 记录的 id,然后是实际查询:

    last_id = Model.last.id
    records = Model.where(status: active).or(Model.where(id: last_id))
    

    您将有 2 个查询,但第一个查询会非常贬值,而第二个查询比将所有结果转换为数组并执行 uniq 快得多。

    【讨论】:

      猜你喜欢
      • 2019-01-09
      • 2019-02-25
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      • 2012-10-25
      • 2019-06-19
      • 2014-06-19
      • 1970-01-01
      相关资源
      最近更新 更多