Rails несколько AR-операций (min, max, avg ..) для одного и того же объекта запроса - PullRequest
3 голосов
/ 25 апреля 2019

Я хочу выполнить несколько вычислений, используя один запрос к таблице price_histories, и, наконец, отобразить некоторые статистические данные, используя такие цены, как среднее, минимальное и максимальное и т. Д.

price_histories_controller.rb

price_stats = PriceHistory.where('created_at >= ? AND cast(item_id as integer) = ?', 1.day.ago, params['item_id'])

avg_array = price_stats.group(:day).average(:price).to_a
min_array = price_stats.group(:day).min(:price).to_a
max_array = price_stats.group(:day).max(:price).to_a
count_array = price_stats.group(:day).count(:price).to_a

Это соответствующий код, который вызывает ошибку, я хотел бы выполнить некоторые вычисления для набора сгруппированных данных, но после первого вычисления я продолжаю получать

TypeError (без явного преобразования Symbol в целое число)

В идеале я хотел бы получить объект, подобный этому, для визуализации:

@all_stats = {
  average: avg_array,
  min: min_array,
  max: max_array,
  count: count_array
}

render json: @all_stats

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

Следующий код работает нормально, и я бы хотел, чтобы кто-нибудь указал мне правильное направление, чтобы выяснить, почему это работает хорошо, а при добавлении и дополнительных вычислениях - нет:

    price_stats = PriceHistory.where('created_at >= ? AND cast(item_id as integer) = ?', 1.day.ago, params['item_id'])

    avg_array = price_stats.group(:day).average(:price).to_a

и приводит к:

{
  "average": [
      [
         null,
         "11666.666666666667"
      ],
      [
         "24/4/2019",
         "11666.666666666667"
      ],
      [
          "24",
          "11666.6666666666666667"
      ],
      [
          "2051",
          "11666.6666666666666667"
      ]
  ],
  "min": [],
  "max": [],
  "count": []
}

Другой подход:

      PriceHistory.select(
        "AVG(price) AS average_score, 
        MIN(price) AS average_min, 
        MAX(price) AS average_max, 
        COUNT(*) AS price_count"
      ).where(
        'created_at >= ? AND cast(item_id as integer) = ?', 
        1.day.ago, params['item_id']
      ).group(:day)

Ошибка:

ArgumentError (вызовите `select 'хотя бы с одним полем):

1 Ответ

5 голосов
/ 25 апреля 2019

Я думаю, что это должно работать:

PriceHistory.where(
  'created_at >= ? AND cast(item_id as integer) = ?',
  1.day.ago,
  params['item_id']
).group(:day).select(
  "SUM(price) AS sum_price",
  "MAX(price) AS max_price",
  "MIN(price) AS min_price",
  "AVG(price) AS avg_price",
  "day"
)

Это вернет вам массив записей, каждая из которых имеет методы day, sum_price, max_price, min_price и avg_price.

Обратите внимание, что имена функций SQL могут отличаться в зависимости от вашей базы данных

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...