2013-02-27 24 views
12

Nagrywam ile razy użytkownicy oglądają serię filmów. Teraz próbuję utworzyć wykres liczby użytkowników oglądających każdego wideo każdego dnia.szyny COUNT SELECT DISTINCT

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

produkuje 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 

która produkuje poprawne wyniki dla wszystkich filmów oglądanych każdego dnia, ale jak powiedziałem, chcę tylko pokazać każdemu użytkownikowi raz.

SQL Chcę to

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 

więc pomyślałem

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

by robić to, co chciałem. Ale powoduje to raczej niż haszowanie.

Wszelkie pomysły?

używam szyn 3.1 i MySQL

Odpowiedz

26

Można użyć distinct.count(:attribute_name).

(w Rails 3 użytkowania: count(:user_id, distinct: true) zamiast)

Zatem:

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

Nie mogli przetestować, ale myślę, że będzie produkować SQL jesteś po.

+0

To sposób ładniejszy - dzięki – Edward

+2

przestarzałe w szynach 4 Zobacz http://stackoverflow.com/a/ 19362288/670433 dla rozwiązania, które ma używać ModelName.distinct.count (: nazwa_atrybutu) – s2t2

+0

Jak zwrócisz wszystkie atrybuty modelu? –

11

W Rails 4, stosując (...).uniq.count(:user_id) jak wspomniano w innych odpowiedzi (na to pytanie, a gdzie indziej na SO) będzie faktycznie prowadzić do dodatkowego DISTINCT będąc w zapytaniu:

SELECT DISTINCT COUNT(DISTINCT user_id) FROM ...

Co my mamy do zrobić to użyć ciąg SQL sobie pytanie:

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

co daje nam:

SELECT COUNT(DISTINCT user_id) FROM ...

0

powinien wykorzystywać różne, w szynach 5.0.1, odrębny równego uniq, ale: [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"