sql >> Databáze >  >> RDS >> PostgreSQL

Vypočítejte maximální počet souběžných uživatelských relací

Odečtěte 30 minut od konce (nebo začátku) každého časového rozsahu. Pak v zásadě postupujte tak, jak je uvedeno v mé odkazované "jednoduché" odpovědi (všude upravte 30 minut správným směrem). Rozsahy kratší než 30 minut jsou a priori eliminovány – což dává smysl, protože nikdy nemohou být součástí 30minutového nepřetržitého překrývání. Také zrychluje dotaz.

Výpočet pro všechny dny v říjnu 2019 (příkladový rozsah):

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 zde

Mějte na paměti, že LOCALTIMESTAMP závisí na časovém pásmu aktuální relace. Zvažte použití timestamptz v tabulce a CURRENT_TIMESTAMP namísto. Viz:




  1. Získávání dat pro graf histogramu

  2. Existuje způsob, jak zobrazit výsledky PRINT pomocí ovladače SQL serveru JDBC?

  3. mysql týden od pondělí do neděle

  4. Jak vypsat aktivní / otevřená připojení v Oracle?