sql >> Base de Datos >  >> RDS >> PostgreSQL

Calcular el número máximo de sesiones de usuario simultáneas

Deduzca 30 minutos del final (o inicio) de cada rango de tiempo. Luego, básicamente proceda como se describe en mi respuesta "simple" referenciada (ajustando los 30 min en la dirección correcta en todas partes). Los rangos de menos de 30 minutos se eliminan a priori, lo que tiene sentido ya que nunca pueden ser parte de un período de 30 minutos de superposición continua. También hace que la consulta sea más rápida.

Cálculo para todos los días de octubre de 2019 (rango de ejemplo):

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 aquí

Tenga en cuenta que LOCALTIMESTAMP depende de la zona horaria de la sesión actual. Considere usar timestamptz en su tabla y CURRENT_TIMESTAMP en cambio. Ver: