通过对附近的时间戳进行分组来查找用户会话

时间:2014-11-12 17:15:05

标签: sqlite timestamp group-by date-difference

我想在SQL中基于"不活动时间"中的一些行进行GROUP BY, 这意味着要注意时间戳之间的大差距,以便识别用户 会话。

在sqlite数据库中假设此操作表:

_actions_
| id | userID | timestamp | actionType |

现在,我可以查看按小时,月份,年份等分组的所有用户操作及其类型。

SELECT 
    userID, strftime('%H', timestamp), group_concat(actionType)
FROM 
    actions 
GROUP BY userID, strftime('%H', timestamp);

然而,这并不完全是我想要的。考虑一下:

| 1 | 333 | 13.11.2014-20:59 | action6 |
| 2 | 333 | 13.11.2014-21:01 | action3 |
| 3 | 333 | 13.11.2014-21:47 | action5 |

我的示例合并到第1行和第2行+ 3,但是如果我们假设会话超时 30分钟我们应该得到第1 + 2行和第3行。任何sql-ideas?

当然可以加载数据库和R,Pandas等并检查每个用户,如果current_timestamp - last_timestamp> 30分钟,但这真的是要走的路吗?

1 个答案:

答案 0 :(得分:0)

要计算某行是会话中第一行的位置,请检查前30分钟内是否存在任何其他行:

SELECT *,
       NOT EXISTS (SELECT 1
                   FROM actions AS prev
                   WHERE userid = actions.userid
                     AND timestamp < actions.timestamp
                     AND timestamp >= datetime(actions.timestamp, '-30 minutes')
                  ) AS first
FROM actions;

id          userid      timestamp         actiontype  first     
----------  ----------  ----------------  ----------  ----------
1           333         2014-11-13 20:59  action6     1         
2           333         2014-11-13 21:01  action3     0         
3           333         2014-11-13 21:47  action5     1         

但是他并没有直接帮助分组;我们需要一些对于组中所有行都是唯一的值。

让我们获取组中第一行的ID。 要查找当前行组的第一行,我们将 last 行作为某些组的第一行,而不在之后当前行:

SELECT *,
       (SELECT id
        FROM actions AS first
        WHERE userid = actions.userid
          AND timestamp <= actions.timestamp
          AND NOT EXISTS (SELECT 1
                          FROM actions AS prev
                          WHERE userid = first.userid
                            AND timestamp < first.timestamp
                            AND timestamp >= datetime(first.timestamp, '-30 minutes')
                         )
        ORDER BY timestamp DESC
        LIMIT 1
       ) AS sessionid
FROM actions;

id          userid      timestamp         actiontype  sessionid 
----------  ----------  ----------------  ----------  ----------
1           333         2014-11-13 20:59  action6     1         
2           333         2014-11-13 21:01  action3     1         
3           333         2014-11-13 21:47  action5     3         

要使此查询有效,必须将timestamp列编入索引。