Как перечислить только один столбец результата Active Record - PullRequest
0 голосов
/ 01 марта 2012

Представьте себе сценарий,

У меня есть таблица Day_fee (date (Date), fee (Integer))

Я хочу иметь список только с месяцами таблицы, дляпример:

Day_fee
date(Date)  fee(Int)
----------|---------
2012/03/27   1
2012/03/26   2
2012/03/25   2
2012/05/01   3
2012/05/02   3
2012/07/01   2
2013/04/01   2
2013/05/01   1

Результат => список с 03, 05 и 07, без повторения месяцев.

И другой большой вопрос:

Я бы хотелсписок хешей с месяцем и годом, например {"03" => "2012", "04" => "2013", "05" => "2013", "05" => "2012", "07"=>" 2012 "}, без повторения месяцев, возможно, в таблице может быть больше лет с тем же месяцем

Поскольку, после этого я хочу показать HTML-таблицу с месяцами и разбить ее на страницы.

Мысли?

Спасибо за помощь.

Ответы [ 5 ]

1 голос
/ 01 марта 2012

Самая короткая строка для Rails 3.2 - DayFee.pluck(:date).map(&:month).uniq, но более быстрое решение зависит от БД, а для postgres - DayFee.select("EXTRACT(MONTH FROM date) as month").group(:month).map(&:month)

1 голос
/ 01 марта 2012

Попробуйте это:

Если вы используете Postgres DB

# Postgres
DayFee.sum(:fee, :group => "EXTRACT(MONTH FROM date)")

=> #<OrderedHash {"3" => 5, "5"=> 6, "7"=> 2}

Если вы используете MySQL

DayFee.sum(:fee, :group => "MONTH(date)")

Редактировать

Судя по вашему комментарию, вам нужны другие данные:

Postgres

DayFee.count(:fee, :group => "date_trunc('month', date)").
  map{|d, k| Date.parse(d)}.
  inject({}){|h, d| h[d.month]=d.year;h}

MySQL

DayFee.count(:fee, :group => "DATE_FORMAT(date, '%Y-%m')").
  map{|d, k| Date.parse(d+"-00 00:00")}.
  inject({}){|h, d| h[d.month]=d.year;h}

Чтобы получить 2D массив

DayFee.count(:fee, :group => "date_trunc('month', date)", 
    :order => "date_trunc('month', date) ASC").
  map{|d, k| Date.parse(d)}.
  map{|h, d| [d.month, d.year]}

# [["03", "2012"], ["03", "2013"], ["03", "2014"]]

Получить хэш с коллекцией лет

DayFee.count(:fee, :group => "date_trunc('month', date)").
  map{|d, k| Date.parse(d)}.
  inject({}){|h, d| (h[d.month]||=[]) << d.year;h}

# {"03" => ["2012", "2013", "2014"]}
0 голосов
/ 01 марта 2012

Если таблица DayFee мала, я бы использовал:

DayFee.all.map{ |df| df.date.month }.uniq

Если таблица DayFee велика, используйте одно из следующих:

# Rails 3.2+
# Never used pluck, but I think it works this way
DayFee.select("MONTH(date) as month").group_by(:month).pluck(:month)

# Rails < 3.2
DayFee.connection.select_values "select MONTH(date) as month from day_fees group by month"
0 голосов
/ 01 марта 2012

Поскольку вы храните даты, а не только названия месяцев (цифры), вам необходимо получить список всех дат:

DayFee.select(:date).uniq   ## active record should generate the correct distinct statement to avoid data redundancy

, чем вы можете найти уникальные месяцы:

DayFee.select(:date).uniq.map{|d| d.gsub(/.+\/(.+)\/.+/, '\1')}.uniq
0 голосов
/ 01 марта 2012

Я думаю, что вам нужен GROUP метод ActiveRecord, затем с использованием функции Month () в mySQL.

Day_fee.select("Month(date) as month, sum(fee) as sum_fee)").group("Month(date)")

Это должно вернуть объект Day_feeтри месяца и сумма сбора.

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