Rails, ActiveRecord и подзапросы

У меня есть база данных postgresql с почасовыми записями о потреблении газа. Теперь мне нужно найти дни с наибольшим потреблением для каждого месяца.

В простом SQL я бы использовал такие подзапросы:

SELECT 
    DATE_TRUNC('month', day) AS month,
    MAX(dailyconsumption) as maxconsumption
FROM (
    SELECT 
        DATE_TRUNC('day', date) AS day,
        SUM(consumption) AS dailyconsumption
    FROM Records
    GROUP BY day
) t
GROUP BY month

Однако я не знаю, как лучше всего (или вообще) сделать это на рельсах. Я ценю любой вклад. Должен ли я обойти ActiveRecord? Производительность является высоким приоритетом.

Спасибо!


person potofski    schedule 14.04.2016    source источник


Ответы (2)


Ваш подзапрос должен быть воссоздан примерно так:

subquery = Records
  .all
  .select("DATE_TRUNC('day', date) AS day", "SUM(consumption) AS dailyconsumption")
  .group("day")

Для запроса из подзапроса вместо таблицы вы используете from.

Records.select(...).from(subquery)

Обратите внимание, что subquery является отношением ActiveRecord. Не актуальные данные. Он преобразуется в SQL во втором операторе, и все это выполняется на стороне БД.

person z5h    schedule 14.04.2016
comment
Спасибо! Я не знал о «.from». Где лучше всего определить эти подзапросы? Контроллер? - person potofski; 15.04.2016
comment
@potofski, где их лучше разместить, обсуждается. Текущие практики Rails предлагают использовать как можно меньше контроллера и выполнять работу в модели. - person z5h; 15.04.2016

Если производительность имеет высокий приоритет, рассмотрите возможность использования представления, представление может быть представлено в Active Record как обычная модель, вы даже можете рассмотреть возможность использования материализованного представления и периодически обновлять записи, таким образом, вам не нужно будет вычислять все каждый раз. .

См. жемчужину живописи, чтобы добавить представления и материализованные представления как часть ваших миграций.

person Mario Carrion    schedule 14.04.2016