postgresql SQL查找访问者总数最大的时间戳

5us2dqdw  于 2023-05-06  发布在  PostgreSQL
关注(0)|答案(3)|浏览(139)

我花了很多时间来解决这个问题。所以,我有表用户:
| 在时间戳|用户数|事件类型|
| --------------|--------------|--------------|
| 十万|二|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查询,这将计算它的权利😅,我将非常感谢您的帮助!

8nuwlpux

8nuwlpux1#

如果去掉partition by,你可以用你的初始方法通过算术来实现这一点:demo

SELECT at_timestamp, 
       sum(users_count*(2*event_type-1)) OVER (ORDER BY at_timestamp)
FROM users_events
ORDER BY at_timestamp;

那是因为

  • event_type似乎是integer
  • 2 * 0 - 1-1,并且
  • 2 * 1 - 11

将其用作乘数,0event_type导致从步进和中减去相应的users_count1event_type导致users_count的相加

ymzxtsji

ymzxtsji2#

简明扼要:CASE WHEN乘数,从@shawnt00开始,在运行求和表达式中使用窗口子句。我使用一个 * 命名窗口 *,因为我发现它更可读,PostgreSQL允许它。
最后,通过运行和降序并应用LIMIT 1进行排序:

marco ~/1/Vertica/supp $ psql -af rsum.sql
WITH
-- Your in data ...
indata(at_timestamp,users_count,event_type) AS (
          SELECT 100000,2,1
UNION ALL SELECT 100001,4,1
UNION ALL SELECT 100003,5,0
UNION ALL SELECT 100005,1,1
UNION ALL SELECT 100006,3,1
UNION ALL SELECT 100008,2,0
UNION ALL SELECT 100008,1,1
)
-- real query starts here ...
SELECT 
  *
, SUM(users_count * CASE event_type WHEN 1 THEN 1 ELSE -1 END) OVER w AS runsum
FROM indata
WINDOW w AS (ORDER BY at_timestamp)
ORDER BY 4 DESC LIMIT 1;
 at_timestamp | users_count | event_type | runsum 
--------------+-------------+------------+--------
       100001 |           4 |          1 |      6
wgmfuz8q

wgmfuz8q3#

with tallied as (
    select *,
        sum(user_count
              * case when event_type = 1
                     then 1 else -1 end) over (
            order by at_timestamp) as tally
    from T
), ranked as (
    select *,
        dense_rank() over (
            order by tally desc) as dr
    from tallied
) 
select * from ranked where dr = 1;

由于排序中可能存在并列关系,因此使用dense_rank()过滤最大输出行。

相关问题