数年にわたるアクティビティ ログがあります。アプリケーションの各ユーザーの毎週のエンゲージメントを計算するように依頼されました。私はエンゲージメントを、特定の週に記録された 1 つ以上のアクティビティを実行するユーザーとして定義します。
これらのアクティビティをグループ化し、ユーザーごとに週ごとにカウントするにはどうすればよいですか? 私はさまざまな投稿をたくさん読みましたが、ruby メソッド、sql、または arel 構文のどれが最適かについて議論があるようです。私は 500 人を超えるユーザーを持っていないので、パフォーマンスは簡潔なものほど重要ではありません。
私はこれをうまく試しました:
user = User.first.activity_logs.group_by { |m| m.created_at.beginning_of_week }
# => {Mon, 11 Mar 2013 00:00:00 EDT -04:00=>
[#<ActivityLog id: 12345, user_id: 429, ... ]}
次に、エラーなしで何かを返すことができる唯一の次のステップ:
user.map { |week| week.count } => [2, 2, 2, 2, 2, 2, 2, 2]
だから私はこれを複雑にしすぎているようです。アクティビティの数を週ごとに簡潔にカウントし、それを各ユーザーに対して行うにはどうすればよいですか?
マネージャー向けのヒート マップやその他のグラフを作成するために、最終的にスプレッドシート (たとえば、以下) に貼り付けることができるものが欲しいだけです。
| User | Week | Activity|
| ------------- | :-------------: | -------:|
| jho | 2013-1 | 20 |
| bmo | 2013-1 | 5 |
| jlo | 2013-1 | 11 |
| gdo | 2013-2 | 2 |
| gdo | 2013-5 | 3 |
| jho | 2013-6 | 5 |
編集
他の参考資料として:
Rails 3.1
Using PostgreSQL 9.1.4 これ
は ruby on rails のスキーマ ファイルです。
create_table "activity_logs", :force => true do |t|
t.integer "user_id"
t.string "activity_type"
t.datetime "created_at"
t.datetime "updated_at"
end
| ------+| --------+| ----------------+| ----------------+ | ----------------+ |
| id | user_id | activity_type | created_at | updated_at |
| ------+| --------+| ----------------+| ----------------+ | ----------------+ |
| 28257 | 8 | User Signin | 2013-02-14 1... | 2013-02-14 1... |
| 25878 | 7 | Password Res... | 2013-02-03 1... | 2013-02-03 1... |
| 25879 | 7 | User Signin | 2013-02-03 1... | 2013-02-03 1... |
| 25877 | 8 | Password Res... | 2013-02-03 1... | 2013-02-03 1... |
| 19325 | 8 | Created report | 2012-12-16 0... | 2012-12-16 0... |
| 19324 | 9 | Added product | 2012-12-16 0... | 2012-12-16 0... |
| 18702 | 8 | Added event | 2012-12-15 1... | 2012-12-15 1... |
| 18701 | 1 | Birthday Email | 2012-12-15 0... | 2012-12-15 0... |
| ------+| --------+| ----------------+| ----------------+ | ----------------+ |
解決
@Erwin Brandstetter のコマンドを変更すると、コマンド ラインで次のように目的の結果が得られました。
ActivityLogs.find_by_sql("
SELECT user_id, to_char(created_at, 'YYYY-WW') AS week, count(*) AS activity
FROM activity_logs
GROUP BY 1, 2
ORDER BY 1, 2;")