PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Calcola il numero massimo di sessioni utente simultanee

Sottrarre 30 minuti dalla fine (o dall'inizio) di ogni fascia oraria. Quindi sostanzialmente procedi come indicato nella mia risposta "semplice" di riferimento (regolando per i 30 min nella giusta direzione ovunque). Gli intervalli inferiori a 30 minuti vengono eliminati a priori, il che ha senso in quanto non possono mai far parte di un periodo di 30 minuti di sovrapposizione continua. Inoltre rende la query più veloce.

Calcolo per tutti i giorni di ottobre 2019 (intervallo di esempio):

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<>violino qui

Tieni presente che LOCALTIMESTAMP dipende dal fuso orario della sessione corrente. Prendi in considerazione l'utilizzo di timestamptz nella tabella e CURRENT_TIMESTAMP invece. Vedi: