如何用PostgreSQL查询访客总数峰值对应的at_timestamp
解决方法
要正确计算每个时刻的实时访客数并找到峰值时刻,核心是将进出事件转换为正负数值后全局累计,而非按事件类型分区。以下是具体步骤和SQL方案:
1. 转换事件数值
先把event_type对应的人数变化转为正负值:
- 进入事件(
event_type=1):users_count为正,直接累加 - 离开事件(
event_type=0):users_count为负,做减法
2. 计算实时累计访客数
使用窗口函数SUM() OVER (ORDER BY at_timestamp)对转换后的数值进行全局累计,同一时刻的所有事件会被一次性计算,得到该时刻的最终访客数。
3. 筛选峰值时刻
通过CTE或子查询找到累计访客数的最大值,再匹配对应的at_timestamp。
完整PostgreSQL查询语句
WITH running_user_counts AS ( SELECT at_timestamp, -- 转换事件为正负数值后累计 SUM(CASE WHEN event_type = 1 THEN users_count ELSE -users_count END) OVER (ORDER BY at_timestamp) AS current_users FROM users_events -- 若实际表名为users,替换为users ) SELECT at_timestamp FROM running_user_counts WHERE current_users = (SELECT MAX(current_users) FROM running_user_counts);
验证示例数据
对给定的示例数据,该查询会计算出各时刻的访客数:
- 100000: 2
- 100001: 2+4=6(峰值)
- 100003: 6-5=1
- 100005: 1+1=2
- 100006: 2+3=5
- 100008: 5-2+1=4
最终返回100001,符合预期。
为什么你的之前的查询不对
你之前的查询按event_type分区,导致进入和离开事件的累计是分开的,无法得到全局总访客数;同时LAG()的用法也不符合需求——我们需要的是全局连续累计,而非按事件类型的差值计算。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

