每小时重叠并发会话 PSQL
Overlapping Concurrent Sessions PSQL for each hour
一段时间以来,我一直在努力寻找合适的解决方案。我有一个 table 名为 sessions.
table 有 3 个字段:
- session_id - 表示用户会话的唯一标识
- 时间戳 - 用户执行操作的时间
- 操作 - 登录或注销
...
我跟踪用户登录和退出的时间。
session_id
action
timestamp
1
login
2021-11-09 10:03
2
login
2021-11-09 10:15
1
logout
2021-11-09 10:48
3
login
2021-11-09 11:03
4
login
2021-11-09 11:43
5
login
2021-11-09 14:14
5
logout
2021-11-09 15:03
3
logout
2021-11-09 15:08
4
logout
2021-11-09 16:03
2
logout
2021-11-09 17:01
基本上,我想要一个输出 table,它会显示每小时有多少个并发会话:
timestamp
concurrent_sessions
2021-11-09 10:00
2
2021-11-09 11:00
3
2021-11-09 12:00
3
2021-11-09 13:00
3
2021-11-09 14:00
4
2021-11-09 15:00
4
2021-11-09 16:00
2
2021-11-09 17:00
1
首先,创建一个 table 时间戳范围,然后加入一个 table 时间戳、聚合和计数:
SELECT times.t, count(*)
FROM generate_series(
TIMESTAMP '2021-11-09 10:00:00',
TIMESTAMP '2021-11-09 17:00:00',
INTERVAL '1 hour'
) AS times(t)
LEFT JOIN (SELECT session_id,
tsrange(li.timestamp, lo.timestamp, '[]') AS range
FROM mytable AS li
LEFT JOIN mytable AS lo USING (session_id)
WHERE li.action = 'login'
AND lo.action = 'logout'
) AS q
ON q.range @> times.t
GROUP BY times.t;
ORDER BY times.t
一段时间以来,我一直在努力寻找合适的解决方案。我有一个 table 名为 sessions.
table 有 3 个字段:
- session_id - 表示用户会话的唯一标识
- 时间戳 - 用户执行操作的时间
- 操作 - 登录或注销
...
我跟踪用户登录和退出的时间。
session_id | action | timestamp |
---|---|---|
1 | login | 2021-11-09 10:03 |
2 | login | 2021-11-09 10:15 |
1 | logout | 2021-11-09 10:48 |
3 | login | 2021-11-09 11:03 |
4 | login | 2021-11-09 11:43 |
5 | login | 2021-11-09 14:14 |
5 | logout | 2021-11-09 15:03 |
3 | logout | 2021-11-09 15:08 |
4 | logout | 2021-11-09 16:03 |
2 | logout | 2021-11-09 17:01 |
基本上,我想要一个输出 table,它会显示每小时有多少个并发会话:
timestamp | concurrent_sessions |
---|---|
2021-11-09 10:00 | 2 |
2021-11-09 11:00 | 3 |
2021-11-09 12:00 | 3 |
2021-11-09 13:00 | 3 |
2021-11-09 14:00 | 4 |
2021-11-09 15:00 | 4 |
2021-11-09 16:00 | 2 |
2021-11-09 17:00 | 1 |
首先,创建一个 table 时间戳范围,然后加入一个 table 时间戳、聚合和计数:
SELECT times.t, count(*)
FROM generate_series(
TIMESTAMP '2021-11-09 10:00:00',
TIMESTAMP '2021-11-09 17:00:00',
INTERVAL '1 hour'
) AS times(t)
LEFT JOIN (SELECT session_id,
tsrange(li.timestamp, lo.timestamp, '[]') AS range
FROM mytable AS li
LEFT JOIN mytable AS lo USING (session_id)
WHERE li.action = 'login'
AND lo.action = 'logout'
) AS q
ON q.range @> times.t
GROUP BY times.t;
ORDER BY times.t