2013-02-27 21 views
12

Tôi đang ghi lại số lần người dùng xem một loạt video. Bây giờ tôi đang cố gắng tạo biểu đồ về số người dùng xem video bất kỳ mỗi ngày.đường ray COUNT CHỌN DISTINCT

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

tạo ra 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 

trong đó sản xuất các kết quả chính xác cho tất cả video xem mỗi ngày, nhưng như tôi đã nói tôi chỉ muốn hiển thị mỗi người dùng một lần.

Các sql tôi muốn là

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 

vì vậy tôi nghĩ

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') 

sẽ làm những gì tôi muốn. Nhưng điều này cho phép

[#<UserVideoWatching >, #<UserVideoWatching >] 

chứ không phải là băm.

Bất kỳ ý tưởng nào?

Tôi đang sử dụng đường ray 3.1 và mysql

Trả lời

26

Bạn có thể sử dụng distinct.count(:attribute_name).

(Trong Rails 3 sử dụng: count(:user_id, distinct: true) thay)

Như vậy:

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

Không thể kiểm tra nhưng tôi nghĩ rằng sẽ tạo ra SQL bạn đang sau.

+0

Đó là cách đẹp hơn - nhờ – Edward

+2

bị phản đối trong đường ray 4 thấy http://stackoverflow.com/a/ 19362288/670433 cho giải pháp đó là sử dụng ModelName.distinct.count (: attribute_name) – s2t2

+0

Làm thế nào để bạn trả về tất cả các thuộc tính của mô hình? –

11

Trong Rails 4, sử dụng (...).uniq.count(:user_id) như đã đề cập trong câu trả lời khác (cho câu hỏi này và các nơi khác trên SO) thực sự sẽ dẫn đến thêm một DISTINCT là trong truy vấn:

SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...

Những gì chúng ta thực sự phải làm là sử dụng một chuỗi SQL mình:

(...).count("DISTINCT user_id")

nào cho chúng ta:

SELECT COUNT(DISTINCT user_id) FROM ...

0

có nên sử dụng riêng biệt, trong đường ray 5.0.1, uniq bình đẳng rõ rệt, nhưng: [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"