0

我有一个带有这样的表的 Rails 应用程序:

编号 | parent_id | 日期时间_a | 日期时间_b | 日期时间_c
1 | 55 | 2013-08-03 11:00:00 | 空 | 无效的
2 | 55 | 空 | 2013-08-04 13:01:11 | 无效的
3 | 56 | 2013-08-02 17:33:23 | 空 | 无效的
4 | 56 | 空 | 2013-08-01 18:00:00 | 无效的
5 | 56 | 空 | 空 | 2013-07-12 07:45:00

我想编写三个 ActiveRecord 范围,每个 parent_id 只返回一条记录,并为特定 datetime_x 列选择具有最新日期时间的记录,并将其缩小到填充了该 datetime_x 列的行。如果一个特定的 parent_id 有多个 datetime_x 列的记录,那么只有当我们缩小到的 datetime_x 是所有现有的最新的时,它才应该返回一行。因此 datetime_a 的范围将返回:

编号 | parent_id | 日期时间_a | 日期时间_b | 日期时间_c
3 | 56 | 2013-08-02 17:33:23 | 空 | 无效的

我们得到了 parent_id 56 的一行,因为 datetime_a 是三个日期时间中最晚的一个。我们没有为 parent_id 55 返回任何行,因为记录 2 的 datetime_b 晚于记录 1 的 datetime_b。

编号 | parent_id | 日期时间_a | 日期时间_b | 日期时间_c
2 | 55 | 空 | 2013-08-04 13:01:11 | 无效的

我们得到 parent_id 55 的一行,因为记录 2 具有三个 datetime_x 列的最新日期时间。我们没有得到 parent_id 56 记录,因为 datetime_a 晚于三个 parent_id 56 记录的 datetime_b。

这是我到目前为止所拥有的,它不起作用:(假设模型是 Foo,表是 foo):

scope :datetime_a, ->{ select('foo.parent_id, MAX(COALESCE(datetime_a, datetime_b, datetime_c))').group('foo.parent_id').where('datetime_a IS NOT NULL') }

也试过这个:

scope :datetime_a, ->{ select('DISTINCT ON (foo.parent_id) *').where('datetime_a IS NOT NULL').order('MAX(COALESCE(datetime_a, datetime_b, datetime_c))')

我正在使用 Postgres,因此欢迎任何仅限 Postgres 的答案。

4

1 回答 1

1

Solved it this way:

scope :datetime_a, ->{ find_by_sql('SELECT * FROM (SELECT DISTINCT ON (foo.parent_id) * FROM foo ORDER BY foo.parent_id, GREATEST(COALESCE(datetime_a, datetime_b, datetime_c)) DESC) AS UNIQ_PARENT WHERE UNIQ_PARENT.datetime_a IS NOT NULL')  }
于 2013-08-10T01:41:26.730 回答