复杂Rails Active Record查询选择具有真实结果的记录,以便当天最新更新其他创建的记录

时间:2017-12-21 08:02:57

标签: sql ruby-on-rails postgresql activerecord

我在表格中有以下重要的列,

  • customer_approval(布尔值)
  • created_at(datetime)
  • updated_at(日期时间)

当天可能存在多条记录。一天的这些记录可能将customer_approval标记为TRUE。

我们如何编写查询来获取结果集如下:

  1. 即使当天有多个记录,也每天只选择一条记录
  2. 必须首先选择记录来记录customer_approval为真的
  3. 如果记录不符合上述条件,请选择当天根据created_at或updated_at列创建或更新的最新条目
  4. 根据日期范围(从日期 - 到日期)选择所有记录。
  5. 另外添加一个例子: 表数据

    +--------+-------------------+------------+------------+
    | row_id | customer_approval | created_at | updated_at |
    +--------+-------------------+------------+------------+
    |      1 | TRUE              | 2017-12-01 | 2017-12-01 |
    |      2 | FALSE             | 2017-12-01 | 2017-12-01 |
    |      3 | NIL               | 2017-12-01 | 2017-12-01 |
    |      4 | NIL               | 2017-12-02 | 2017-12-02 |
    |      5 | FALSE             | 2017-12-03 | 2017-12-03 |
    |      6 | NIL               | 2017-12-03 | 2017-12-03 |
    |      7 | NIL               | 2017-12-04 | 2017-12-05 |
    +--------+-------------------+------------+------------+
    

    2017-12-01日期范围的预期结果集& 2017-12-05:

    +--------+-------------------+------------+------------+
    | row_id | customer_approval | created_at | updated_at |
    +--------+-------------------+------------+------------+
    |      1 | TRUE              | 2017-12-01 | 2017-12-01 |
    |      4 | NIL               | 2017-12-02 | 2017-12-02 |
    |      6 | NIL               | 2017-12-03 | 2017-12-03 |
    |      7 | NIL               | 2017-12-04 | 2017-12-05 |
    +--------+-------------------+------------+------------+
    

    提前致谢。

    P.S。对于糟糕的表格格式感到抱歉。

2 个答案:

答案 0 :(得分:0)

Postgresql查询

SELECT DISTINCT ON (created_at) row_id, customer_approval, created_at
FROM the_table
ORDER BY customer_approval DESC, created_at DESC;

在rails中

TheTable.select("DISTINCT ON (created_at) row_id, customer_approval, created_at")
        .order(customer_approval: :desc, created_at: :desc )

答案 1 :(得分:0)

我知道它并不完美,你应该考虑例外。

<强>模型

class Customer < ApplicationRecord

  scope :approval, -> { where customer_approval: true }
  scope :waiting, -> { where customer_approval: nil }

  scope :for_day, ->(date) {
    where(
      arel_table[:created_at].eq(date)
      .or(arel_table[:updated_at].eq(date))
    )
  }

  def self.last_change
    order(created_at: :desc, updated_at: :desc).first
  end
end

<强>控制器

def fetch_customers(first, last)
  result = []

  first.upto(last) do |date|
    customer = Customer.for_day(date).approval.first
    customer ? (result << customer) : (result << Customer.for_day(date).waiting.last_change)
  end

  result
end

# first = Date.parse('2017-12-01')
# last = Date.parse('2017-12-05')
# fetch_customer(first, last)

P.s。希望您的rails版本4+(对于Arel表格)