PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Berechnen Sie die maximale Anzahl gleichzeitiger Benutzersitzungen

Ziehen Sie 30 Minuten vom Ende (oder Beginn) jedes Zeitbereichs ab. Gehen Sie dann grundsätzlich so vor, wie in meiner referenzierten "einfachen" Antwort beschrieben (Anpassung für die 30 min überall in die richtige Richtung). Bereiche, die kürzer als 30 Minuten sind, werden a priori eliminiert – was sinnvoll ist, da diese niemals Teil einer 30-minütigen Periode kontinuierlicher Überschneidung sein können. Macht die Abfrage auch schneller.

Berechnung für alle Tage im Oktober 2019 (Beispielbereich):

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 hier

Beachten Sie, dass LOCALTIMESTAMP hängt von der Zeitzone der aktuellen Sitzung ab. Erwägen Sie die Verwendung von timestamptz in Ihrer Tabelle und CURRENT_TIMESTAMP stattdessen. Siehe: