2013-02-27 18 views
12

Я записываю, сколько раз пользователи просматривают серию видеороликов. Теперь я пытаюсь составить график количества пользователей, которые смотрят видео каждый день.rails COUNT SELECT DISTINCT

UserVideoWatching.where("created_at >= ? AND user_id != ?",1.month.ago, User.elephant.id).group("DATE(created_at)").reorder('created_at').count 

производит SQL

SELECT COUNT(*) AS count_all, DATE(created_at) AS date_created_at FROM `user_video_watchings` WHERE (created_at >= '2013-01-27 10:43:24' AND user_id != 7) GROUP BY DATE(created_at) ORDER BY created_at 

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

SQL, я хочу

SELECT COUNT(DISTINCT user_id) AS count_all, DATE(created_at) AS date_created FROM `user_video_watchings` WHERE (created_at >= '2013-01-27 10:33:18' AND user_id != 7) GROUP BY DATE(created_at) ORDER BY created_at 

так я думал

UserVideoWatching.where("created_at >= ? AND user_id != ?",1.month.ago, User.elephant.id).group("DATE(created_at)").reorder('created_at').select('COUNT(DISTINCT user_id) AS count_all, DATE(created_at) AS date_created') 

будет делать то, что я хотел. Но это дает

[#<UserVideoWatching >, #<UserVideoWatching >] 

а не хэш.

Любые идеи?

Я использую рельсы 3.1 и MySQL

ответ

26

Вы можете использовать distinct.count(:attribute_name).

(В Rails 3 использования: count(:user_id, distinct: true) вместо)

Таким образом:

UserVideoWatching.where("created_at >= ? AND user_id != ?", 1.month.ago, User.elephant.id) 
.group("DATE(created_at)").reorder('created_at').distinct.count(:user_id) 

не в состоянии проверить, но я думаю, что будет производить SQL вы после этого.

+0

Это способ лучше - благодаря – Edward

+2

осуждаются в рельсах 4 см http://stackoverflow.com/a/ 19362288/670433 для решения, которое должно использовать ModelName.distinct.count (: attribute_name) – s2t2

+0

Как вы возвращаете все атрибуты модели? –

11

В 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 ...

0

должен использовать четким, в рельсах 5.0.1, отчетливой равной Uniq, но: [11] pry(main)> Needremember.distinct.count(:word) (1.1ms) SELECT DISTINCT COUNT(DISTINCT "needremembers"."word") FROM "needremembers" [12] pry(main)> Needremember.uniq.count(:word) DEPRECATION WARNING: uniq is deprecated and will be removed from Rails 5.1 (use distinct instead) (called from __pry__ at (pry):12) (0.6ms) SELECT DISTINCT COUNT(DISTINCT "needremembers"."word") FROM "needremembers"