每个登录日期汇总记录

时间:2018-01-26 21:51:24

标签: sql postgresql

我有一个存储用户登录的表,可以简化为:

| user | logindate           |
+------+---------------------+
| 001  | 2018-01-26 10:00:00 |
| 001  | 2018-01-26 11:00:00 |
| 001  | 2018-01-26 12:00:00 |

同样,我有一个用户完成的表记录活动:

| user | activitydate        | activity  |
+------+---------------------+-----------+
| 001  | 2018-01-26 10:24:00 | survey    |
| 001  | 2018-01-26 10:30:00 | poll      |
| 001  | 2018-01-26 11:03:00 | poll      |
| 001  | 2018-01-26 12:08:00 | poll      |
| 001  | 2018-01-26 12:10:00 | survey    |
| 001  | 2018-01-26 12:12:00 | video     |

我想知道每个用户每次登录完成的活动数量。鉴于上面的例子,我希望得到如下结果:

| user | latestLogin         | activityCount |
+------+---------------------+---------------+
| 001  | 2018-01-26 10:00:00 | 2             |
| 001  | 2018-01-26 11:00:00 | 1             |
| 001  | 2018-01-26 12:00:00 | 3             |

我找到了一种方法,即使用登录表(在活动之前登录)加入每个活动,并获得每个活动的最大登录次数。我可以使用SQLFiddle - http://sqlfiddle.com/#!9/c3c90d/8

来证明这一点

但是,我觉得这个解决方案很慢。当我在生产环境中运行它时,查询运行的时间太长。我正在研究的时间段内有近85,000条登录记录,以及更多的活动。

有哪些替代解决方案?有没有什么方法可以先查询登录表以找出各种登录段,然后将每个活动绑定到这些段,例如?

1 个答案:

答案 0 :(得分:0)

您可以使用相关子查询获取登录信息:

select a.*,
       (select max(l.logindate)
        from logins l
        where l.user = a.user and a.activitydate >= l.logindate
       ) as logindate
from activities a;

其余的只是聚合。我会使用子查询:

select user, logindate, count(*) as numactivities
from (select a.*,
             (select max(l.logindate)
              from logins l
              where l.user = a.user and a.activitydate <= l.logindate
             ) as logindate
      from activities a
     ) a
group by user, logindate;

SQL Fiddle中的数据与问题中的数据不同,但here是其工作原理的一个示例。