sql >> Database >  >> RDS >> PostgreSQL

Som van tijdsverschil tussen rijen

De speciale moeilijkheid is om de tijdspanne naar het buitenste tijdsbestek niet te missen.
Ervan uitgaande dat de volgende rij voor een gegeven id heeft altijd de tegenovergestelde status.
De kolomnaam ts . gebruiken in plaats van 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;

Retourneert intervallen zoals gevraagd.
ID's zonder vermeldingen in de geselecteerde tijdsperiode worden niet weergegeven. Je zou ze bovendien moeten opvragen.

SQL Fiddle.
Opmerking:ik cast de resulterende total_disconnected naar text in de viool, omdat het type interval wordt weergegeven in een verschrikkelijk formaat.

ID's toevoegen zonder invoer in het geselecteerde tijdsbestek


Toevoegen aan de bovenstaande zoekopdracht (vóór de laatste 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.

Nu alleen ID's zonder vermeldingen in of eerder de geselecteerde tijdsperiode wordt niet weergegeven.



  1. Draaitabel opheffen in MySQL

  2. Eerste X-regels van een database verwijderen

  3. Welke Visual Studio heb ik nodig voor MySQL?

  4. MySQL - CASE vs IF Statement vs IF functie