У меня есть приложение Rails с таблицей, как это:Как написать область Rails ActiveRecord, которая объединяет строки и возвращает только последнюю дату среди трех дат?
id | parent_id | datetime_a | datetime_b | datetime_c 1 | 55 | 2013-08-03 11:00:00 | null | null 2 | 55 | null | 2013-08-04 13:01:11 | null 3 | 56 | 2013-08-02 17:33:23 | null | null 4 | 56 | null | 2013-08-01 18:00:00 | null 5 | 56 | null | null | 2013-07-12 07:45:00
Я хочу написать три ActiveRecord области, которые возвращают только одну запись в parent_id и выбирает запись с последней датой-временем для конкретного столбца datetime_x и сужает до строки с заполненным столбцом datetime_x. Если конкретный parent_id имеет записи для более чем одного столбца datetime_x, он должен возвращать только строку, если datetime_x, с которым мы сужены, является последней из всех существующих. Таким образом, возможности для datetime_a вернутся:
id | parent_id | datetime_a | datetime_b | datetime_c 3 | 56 | 2013-08-02 17:33:23 | null | null
Мы получаем строку для parent_id 56, потому что datetime_a является последним из трех времен даты. Мы получаем ни одна строка не возвращается для parent_id 55, потому что datetime_b для записи 2, позже, чем datetime_b для записи 1.
id | parent_id | datetime_a | datetime_b | datetime_c 2 | 55 | null | 2013-08-04 13:01:11 | null
Мы получаем строку для parent_id 55, потому что запись 2 имеет последнюю DateTime из трех datetime_x колонн. Мы не получаем никаких записей parent_id 56, потому что datetime_a позже, чем datetime_b для трех записей parent_id 56.
Это то, что я до сих пор, что не работает: (при условии, что модель 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 приветствуются.
Это решение является проблематичным, однако, как find_by_sql возвращает массив и не ActiveRecord Collection, которые могут быть соединены. Возможно, есть способ сделать это с помощью isl_table? – Ben
Я думаю, что делать это вручную с помощью SQL может быть вашим единственным вариантом, понимание ActiveRecord о нетривиальном SQL (например, производные таблицы, функции окна, CTEs ...) крайне ограничено. –