22

我正在记录用户观看一系列视频的次数。现在我正在尝试制作每天观看任何视频的用户数量的图表。

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 >]

而不是哈希。

有任何想法吗?

我正在使用 rails 3.1 和 mysql

4

3 回答 3

36

您可以使用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。

于 2013-02-27T11:17:37.297 回答
19

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

于 2015-10-12T20:00:04.770 回答
1

应该使用 distinct,在 rails 5.0.1 中,distinct equal 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"
于 2017-06-01T02:14:14.023 回答