Rails查询:关联是父母的第一个关联记录?

时间:2017-03-23 15:33:09

标签: mysql ruby-on-rails activerecord

我的工作有很多发票,发票属于工作。我想查询第一张发票落在日期范围之间的作业。我有这个问题:

@jobs = Job.joins(:invoices).
  where("invoices.date BETWEEN ? AND ?", @from_date, @to_date).
  where("invoices = job.invoices.first")

第二个where子句是伪代码,但它让你知道我想要做什么。

如果重要的话,我正在使用MYSQL。

3 个答案:

答案 0 :(得分:1)

我的查询将是:

@jobs = Job.where("
  id IN (
    SELECT T1.job_id
    FROM invoices as T1 JOIN (
      SELECT job_id, MIN(id) AS first_id
      FROM invoices
      GROUP BY job_id
    ) as T0 ON T1.id = T0.first_id
    WHERE T1.date > ? AND T1.date < ?
  )
", @from_date, @to_date)

说明:

  • T0包含job_id按job_id
  • 分组的第一个发票ID
  • T1是INVOICE表将在first_id上与T0连接,因此只会选择第一张发票,然后使用给定的日期范围进行过滤
  • Job.where查询子查询中的作业ID

答案 1 :(得分:1)

使用Rails执行此操作的最简单方法是添加范围,如下所示:

has_one  :first_invoice, -> { order('created_at DESC')  }, class_name: 'Invoice'

然后你可以这样做:

@jobs = Job.joins(:first_invoice).where("invoices.date BETWEEN ? AND ?", @from_date, @to_date)

编辑 - 这实际上并不起作用。第一个发票范围适用于作业实例以获取其第一张发票,但在加入时不起作用。

答案 2 :(得分:1)

另一种方法 - 您可以向Job添加一列并存储first_invoice_date(并将其编入索引)。查询,排序,组合范围,显示第一个发票日期等变得更加容易。