PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Calcular o número máximo de sessões de usuário simultâneas


Deduza 30 minutos do final (ou início) de cada intervalo de tempo. Então, basicamente, prossiga conforme descrito na minha resposta "simples" referenciada (ajustando para os 30 min na direção certa em todos os lugares). Intervalos inferiores a 30 minutos são eliminados a priori - o que faz sentido, pois nunca podem fazer parte de um período de 30 minutos de sobreposição contínua. Também torna a consulta mais rápida.

Calculando para todos os dias em outubro de 2019 (intervalo de exemplo):
WITH range AS (SELECT timestamp '2019-10-01' AS start_ts  -- incl. lower bound
                    , timestamp '2019-11-01' AS end_ts)   -- excl. upper bound
, cte AS (
   SELECT userid, starttime
       -- default to current timestamp if NULL
        , COALESCE(endtime, localtimestamp) - interval '30 min' AS endtime
   FROM   usersessions, range r
   WHERE  starttime <  r.end_ts  -- count overlaps *starting* in outer time range
   AND   (endtime   >= r.start_ts + interval '30 min' OR endtime IS NULL)

   )
, ct AS (
   SELECT ts, sum(ct) OVER (ORDER BY ts, ct) AS session_ct
   FROM  (
      SELECT endtime AS ts, -1 AS ct FROM cte
      UNION ALL
      SELECT starttime    , +1       FROM cte
      ) sub
   )
SELECT ts::date, max(session_ct) AS max_concurrent_sessions
FROM   ct, range r
WHERE  ts >= r.start_ts
AND    ts <  r.end_ts            -- crop outer time range
GROUP  BY ts::date
ORDER  BY 1;

db<>fiddle aqui

Esteja ciente de que LOCALTIMESTAMP depende do fuso horário da sessão atual. Considere usar timestamptz em sua tabela e CURRENT_TIMESTAMP em vez de. Ver: