У меня есть набор записей, который включает в себя поле даты, и вы хотите определить, сколько уникальных дат представлено в наборе записей.
Что-то вроде:
Record.find(:all).date.unique.count
но, конечно, это не работает.
У меня есть набор записей, который включает в себя поле даты, и вы хотите определить, сколько уникальных дат представлено в наборе записей.
Что-то вроде:
Record.find(:all).date.unique.count
но, конечно, это не работает.
Для чего нужен следующий SQL:
SELECT COUNT(DISTINCT date) FROM records
ActiveRecord имеет встроенную функцию:
Record.count('date', :distinct => true)
Это немного изменилось в рельсах 4 и выше :distinct => true
теперь устарело. Использование:
Record.distinct.count('date')
Или, если вам нужна дата и номер:
Record.group(:date).distinct.count(:date)
Вне SQL:
Record.find(:all).group_by(&:date).count
ActiveSupport Переменная # group_by является незаменимой.
Как я уже упоминал здесь, в Rails 4 использование (...).uniq.count(:user_id)
, как упоминалось в других ответах (для этого вопроса и в других местах на SO), фактически приведет к дополнительному DISTINCT
находится в запросе:
SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...
Нам действительно нужно использовать строку SQL:
(...).count("DISTINCT user_id")
Что дает нам:
SELECT COUNT(DISTINCT user_id) FROM ...
Детализация ответа:
Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 1, :created_on => '2010-09-29')
Post.create(:user_id => 2, :created_on => '2010-09-29')
Post.create(:user_id => null, :created_on => '2010-09-29')
Post.group(:created_on).count
# => {'2010-09-29' => 4}
Post.group(:created_on).count(:user_id)
# => {'2010-09-29' => 3}
Post.group(:created_on).count(:user_id, :distinct => true) # Rails <= 3
Post.group(:created_on).distinct.count(:user_id) # Rails = 4
# => {'2010-09-29' => 2}
последний #count
в исходном коде rails принимает только 1 параметр.
см. http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-count
поэтому я достиг этого требования на
Record.count('DISTINCT date')
Кроме того, убедитесь, что у вас есть индекс в поле в вашем db, иначе этот запрос быстро станет sloooow.
(Это гораздо лучше сделать в SQL, иначе вы вытащите всю таблицу db в память, чтобы ответить на счет.)