如何计算MySQL中日期的聚合

时间:2010-10-04 18:55:05

标签: mysql

我正在尝试在MySQL中进行累积聚合。

我的原始数据如下所示:(我的日期是月/日/年)

user_id    created_at    source
1          1/1/01        foo
2          1/1/01        foo
3          1/2/01        bar
4          1/2/01        foo
5          1/3/01        foo
     ....

鉴于此,我想做一个看起来像这样的结果:

date    source    total_in_source
1/1/01  foo       2
1/2/01  foo       3
1/3/01  foo       4

其中total_in_source是第一个和当前日期值之间created_at的用户数的总和。

我可以使用相关的子查询来做到这一点,但这有点低效:

select 
date(user.created_at) d,
user.source as user_source,
(select count(*) from users u where u.source = user_source and month(u.created_at) <= month_joined) as total_users_source,
from users user group by d, user_source

我做了一些环顾四周,似乎这样做可能是朝着正确方向迈出的一步:

select date(u1.created_at) as 'd',
u1.source as 'source', 
count(distinct u2.id) as count_users
from users u1, users u2
where
u2.created_at BETWEEN DATE(u1.created_at) AND DATE_ADD(DATE(u1.created_at), interval 1 day) and
group by d, source

但即使这是一个自连接并产生n ^ 2行来迭代(用户*用户)。有关于如何做到这一点的最佳实践吗?

提前感谢。

1 个答案:

答案 0 :(得分:1)

您需要“人工创建”在临时表或直接内联中加入的开始日期和结束日期。

假设您希望开始,结束月份的每个组合,然后在该时间范围内按照您所描述的来源和计数进行细分。你可以这样做:

从用户中选择u.source,sdates.val start,edates.val end,count(*)from(select distinct(date(created_at))val,其中day(created_at)= 1)sdates join(select distinct(date) (created_at))来自用户的val,其中day(created_at)= 1)通过sdates.val,edates.val,u.source;

编辑sdates.val和edates.val group之间的u.created_at上的用户u。

基本上,内部查询“获取日期”,外部查询实际上进行计算。对于项目的每个相关日期,有一个“日期”表可能会有所帮助,因此您可以轻松地加入它而不必执行此伏都教,但如果没有这样做,这似乎有效。< / p>

此外,您可能不希望开始和结束的每个组合,因此您可以使用内部查询的“where”条件或连接的“on”来满足您的需要。

好奇,如果有人有更好的解决方案。