我花了很多时间来解决这个问题。所以,我有表用户:
| 在时间戳|用户数|事件类型|
| --------------|--------------|--------------|
| 十万|二|1|
| 100001|四个|1|
| 100003|五|0|
| 十万零五|1|1|
| 十万六|三|1|
| 十万零八|二|0|
| 十万零八|1|1|
等等
因此,事件类型1表示IN,0表示OUT。我需要找到时间戳,当用户的总和是最高的。在这个例子中,它是100001,因为2 + 4 = 6。5人出局,1人出局。然后1个用户进入,3个用户进入,这意味着在100006 ts处的总用户计数是5。然后在同一时间,2离开和1在等等。我试过使用窗口函数,但没有IF/ELSE或其他东西,但它对我不起作用。我有一些接近,但不完全是我需要的。
我的postgres查询示例
SELECT at_timestamp, sum(users_count) OVER (PARTITION BY event_type ORDER BY at_timestamp)
FROM users_events;
那我试过了
SELECT at_timestamp, sum(users_count) OVER (partition by event_type ORDER BY at_timestamp) - LAG(users_count) OVER (PARTITION BY event_type) FROM users_events;
但它不起作用,因为我需要减去前一个值,如果它是out事件。所以,我需要SQL查询,这将计算它的权利😅,我将非常感谢您的帮助!
3条答案
按热度按时间8nuwlpux1#
如果去掉
partition by
,你可以用你的初始方法通过算术来实现这一点:demo那是因为
event_type
似乎是integer
2 * 0 - 1
是-1
,并且2 * 1 - 1
是1
将其用作乘数,
0
的event_type
导致从步进和中减去相应的users_count
,1
的event_type
导致users_count
的相加ymzxtsji2#
简明扼要:CASE WHEN乘数,从@shawnt00开始,在运行求和表达式中使用窗口子句。我使用一个 * 命名窗口 *,因为我发现它更可读,PostgreSQL允许它。
最后,通过运行和降序并应用LIMIT 1进行排序:
wgmfuz8q3#
由于排序中可能存在并列关系,因此使用
dense_rank()
过滤最大输出行。