sql >> Databasteknik >  >> RDS >> PostgreSQL

Beräkna maximalt antal samtidiga användarsessioner

Dra av 30 minuter från slutet (eller början) av varje tidsintervall. Fortsätt sedan i princip enligt beskrivningen i mitt refererade "enkla" svar (justerar för de 30 min i rätt riktning överallt). Avstånd som är kortare än 30 minuter elimineras a priori - vilket är vettigt eftersom de aldrig kan ingå i en 30 minuters period av kontinuerlig överlappning. Gör också frågan snabbare.

Beräknar för alla dagar i oktober 2019 (exempelintervall):

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<>fiol här

Tänk på att LOCALTIMESTAMP beror på tidszonen för den aktuella sessionen. Överväg att använda timestamptz i tabellen och CURRENT_TIMESTAMP istället. Se:




  1. Citerar kolumnnamn med NHibernate och PostgreSQL

  2. Skicka en HTML-tabellrad till php

  3. Bindning av int64 (SQL_BIGINT) som frågeparameter orsakar fel under körning i Oracle 10g ODBC

  4. Hur kastar jag ett fel i SQL när jag uppdaterar "inte null"-värden i en databastabell