Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Summe Zeitdauer nach Ortswechsel

Folgendes scheint zu funktionieren:

SET @locationID=0,@ts=NULL,@changed=0;

SELECT
  MIN(assetID) AS id
  , MIN(locationID) AS location
  , SUM(secDiff) AS duration
FROM
  (SELECT
    assetID
    , locationID
    , @changed := IF(locationID <> previousLocationID, @changed + 1, @changed) AS changed
    , IFNULL(TIMESTAMPDIFF(SECOND,
                           previousTs,
                           ts
                           ),
             0
      ) AS secDiff
  FROM
    (SELECT
      assetID
      , locationID
      , @locationID AS previousLocationID
      , @locationID := locationID AS currentLocationID
      , ts
      , @ts AS previousTs
      , @ts := ts AS currentTs
    FROM Logs L1
    WHERE assetid = 1157    
    ORDER BY ts
    ) L2
  ORDER BY ts
  ) L3
GROUP BY changed
ORDER BY changed DESC
;

Sehen Sie es in Aktion:SQL Fiddle .

Aktualisierung:

Wenn Sie zusätzliche Tische beitreten müssen, sollten Sie tatsächlich JOIN und nicht Unterauswahl. Da es ein GROUP BY gibt Auf der derzeit äußersten Ebene muss die vorhandene Anweisung in einen weiteren Satz Klammern eingeschlossen werden, um eine Gruppierung über den Faktentabellen zu verhindern. Mit einigen anderen Anpassungen zu diesem Zweck:

SET @locationID=0,@ts=NULL,@changed=0;

SELECT
  A.name
  , L4.assetID
  , L.name
  , L4.locationID
  , duration
FROM
  (SELECT
    MIN(assetID) AS assetID
    , MIN(locationID) AS locationID
    , SUM(secDiff) AS duration
    , changed
  FROM
    (
-- no change in here
    ) L3
  GROUP BY changed
  ) L4
JOIN Asset A
  ON L4.assetID = A.id
JOIN Location L
  ON L4.locationID = L.id
ORDER BY changed DESC
;

Erweiterter SQL Fiddle .

Aktualisierung 2:

Der einfachste Weg, doppelte Einträge zu beheben, sollte DISTINCT sein sie als allerersten Schritt weg:

-- no change here
  (SELECT
    assetID
    , locationID
    , @locationID AS previousLocationID
    , @locationID := locationID AS currentLocationID
    , ts
    , @ts AS previousTs
    , @ts := ts AS currentTs
  FROM
    (SELECT DISTINCT
      assetID
      , locationID
      , ts
    FROM Logs
    WHERE assetid = 1157
    ) L1
  ORDER BY ts
  ) L2
-- no change here either

Diese SQL-Fiddle Rückgaben für die duplizierten Protokolle data dieselbe Ergebnismenge wie SQL Fiddle , wobei die frühere Abfrage für Daten ohne Duplikate ausgeführt wird.

Bitte kommentieren Sie, wenn und da dies Anpassungen / weitere Details erfordert.