首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Ruby、Activerecord或Postgresql中按周对活动进行分组和计数

在Ruby、Activerecord或Postgresql中按周对活动进行分组和计数
EN

Stack Overflow用户
提问于 2013-03-22 01:29:39
回答 2查看 1.1K关注 0票数 3

我有一个跨越几年的活动日志。我被要求为应用程序的每个用户计算每周参与度。我将参与度定义为用户在任何给定的一周内进行一个或多个记录的活动。

如何对这些活动进行分组,并按周对每个用户进行计数?我读了很多不同的帖子,关于ruby methodssql还是arel语法到底是最好的,似乎还存在争论。我没有超过500个用户,所以性能并不是一个重要的问题,而是一个简洁的东西。

我已经成功地尝试过了:

代码语言:javascript
运行
复制
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, ... ]}

然后,下一步我可以无错误地返回任何内容:

代码语言:javascript
运行
复制
user.map { |week| week.count } => [2, 2, 2, 2, 2, 2, 2, 2]

所以看起来我把事情搞得太复杂了。我如何简洁地计算每周的活动数量,并为每个用户这样做?

我只想要一些我可以最终粘贴到电子表格中的东西(例如,下面),以便为经理制作热图或其他图表。

代码语言:javascript
运行
复制
| 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

使用PostgreSQL 9.1.4

以下是ruby on rails中的模式文件

代码语言:javascript
运行
复制
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的命令,我在命令行上得到了想要的结果:

代码语言:javascript
运行
复制
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;")
EN

Stack Overflow用户

发布于 2013-03-22 08:54:00

这里是Postgresql。这里的诀窍是你需要生成你的年周值。在这里,我从日期中提取信息并将其连接起来。

在这里,我保证'2012-01-01‘不会被算作52周。我凌驾于标准之上。根据定义周的方式,您可能需要更改此函数。

代码语言:javascript
运行
复制
create temp table daily_log(person character varying, activity numeric, 
    dayof date);
insert into daily_log values 
     ('bob'    ,1,'2012-01-01')
    ,('bob'    ,1,'2012-01-02')
    ,('bob'    ,0,'2012-01-14')
    ,('charlie',1,'2012-01-01')
    ,('charlie',1,'2012-01-14')

select person 
 ,extract('year' from dayof) || '-' || 
    case when extract('week' FROM dayof) >= 52 
         and extract('month' FROM dayof) = 1 
    then 1 
 else extract('week' FROM dayof) end as weekof
,sum(activity) as activity_cnt
from daily_log
group by weekof, person
order by person, weekof;

这将为您带来:

代码语言:javascript
运行
复制
| person        | weekof          | activity_cnt|
| -------------:| :--------------:| -----------:|
| bob           | 2012-1          | 2           |
| bob           | 2012-2          | 0           |
| charlie       | 2012-1          | 1           |
| charlie       | 2012-2          | 1           |

为什么我用2012,我不知道。

下面是postgresl手册中关于提取周(http://www.postgresql.org/docs/9.2/static/functions-datetime.html)的说明:

“一天所在的一年中的第几个星期。根据定义(ISO 8601),一年的第一周包含该年的1月4日。( ISO-8601一周从星期一开始。)换句话说,一年的第一个星期四在该年的第一周。(仅用于时间戳值)

因此,一月初的日期可能是前一年的52周或53周的一部分。例如,2005-01-01是2004年53周的一部分,2006-01-01是2005年52周的一部分。“

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15554246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档