PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Сума от времевата разлика между редовете

Особената трудност е да не се пропуснат времевите интервали до външната времева рамка.
Приемайки, че следващият ред за всеки даден id винаги има противоположен статус.
Използване на името на колоната ts вместо recordTime :

WITH span AS (
   SELECT '2014-03-01 13:00'::timestamp AS s_from  -- start of time range
        , '2014-03-01 14:00'::timestamp AS s_to    -- end of time range
   )
, cte AS (
   SELECT id, ts, status, s_to
        , lead(ts, 1, s_from) OVER w AS span_start
        , first_value(ts)     OVER w AS last_ts
   FROM   span s
   JOIN   tbl  t ON t.ts BETWEEN s.s_from AND s.s_to
   WINDOW w AS (PARTITION BY id ORDER BY ts DESC)
   )
SELECT id, sum(time_disconnected)::text AS total_disconnected
FROM  (
   SELECT id, ts - span_start AS time_disconnected
   FROM   cte
   WHERE  status = 'Connected'

   UNION  ALL  
   SELECT id, s_to - ts
   FROM   cte
   WHERE  status = 'Disconnected'
   AND    ts = last_ts
   ) sub
GROUP  BY 1
ORDER  BY 1;

Връща интервали според заявките.
Идентификаторите без записи в избрания времеви диапазон не се показват. Ще трябва да ги запитате допълнително.

SQL Fiddle.
Забележка:Прехвърлям получения total_disconnected към text в цигулката, защото типът interval се показва в ужасен формат.

Добавяне на идентификатори без въвеждане в избраната времева рамка


Добавете към заявката по-горе (преди крайния ORDER BY 1 ):

...
UNION  ALL
SELECT id, total_disconnected
   FROM  (
   SELECT DISTINCT ON (id)
          t.id, t.status, (s.s_to - s.s_from)::text AS total_disconnected
   FROM   span     s
   JOIN   tbl      t ON t.ts < s.s_from  -- only from before time range
   LEFT   JOIN cte c USING (id)
   WHERE  c.id IS NULL         -- not represented in selected time frame
   ORDER  BY t.id, t.ts DESC   -- only the latest entry
   ) sub
WHERE  status = 'Disconnected' -- only if disconnected
ORDER  BY 1;

SQL Fiddle.

Сега само идентификатори без записи в или преди избраният период от време не се показва.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. вземете последните три месеца записи от таблицата

  2. psycopg2 :курсорът вече е затворен

  3. Postgres ИЗБЕРЕТЕ ... ЗА АКТУАЛИЗИРАНЕ във функции

  4. Множество бази данни с Rails не работят за отдалечена база данни

  5. PostgreSQL Където условие за броене