PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Suma różnicy czasu między wierszami

Szczególna trudność polega na tym, aby nie przegapić przedziałów czasowych do zewnętrznej ramy czasowej.
Zakładając, że następny wiersz dla dowolnego podanego id zawsze ma odwrotny status.
Korzystanie z nazwy kolumny ts zamiast 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;

Zwraca interwały zgodnie z żądaniem.
Identyfikatory bez wpisów w wybranym zakresie czasu nie są wyświetlane. Musiałbyś je dodatkowo zapytać.

SQL Fiddle.
Uwaga:przesyłam wynikowy total_disconnected do text na skrzypcach, ponieważ typ interval jest wyświetlany w okropnym formacie.

Dodaj identyfikatory bez wpisu w wybranym przedziale czasu


Dodaj do powyższego zapytania (przed ostatecznym 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;

Skrzypce SQL.

Teraz tylko identyfikatory bez wpisów w lub przed wybrany zakres czasu nie jest wyświetlany.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgresql. UTWÓRZ CAST 'znak zmienny' na 'liczba całkowita'

  2. Sortowanie miesięcy podczas konwertowania ich na tekst

  3. Zainicjuj bazę danych Postgres w Docker Compose

  4. Jaka jest definicja indeksu wtórnego w postgresql?

  5. Migracja baz danych PostgreSQL ze środowiska lokalnego do chmury przy użyciu AWS RDS