Mysql
 sql >> Database >  >> RDS >> Mysql

Somma la durata del tempo per cambio di posizione

Quanto segue sembra fare il trucco:

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
;

Guardalo in azione:SQL Fiddle .

Aggiornamento:

Se devi unirti a tavoli aggiuntivi, dovresti effettivamente JOIN e non sottoselezionare. Poiché esiste un GROUP BY al livello attualmente più estremo, l'istruzione esistente deve essere racchiusa in un'altra serie di parentesi, per evitare il raggruppamento sulle tabelle dei fatti. Con alcuni altri aggiustamenti a tal fine:

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
;

SQL Fiddle ampliato .

Aggiornamento 2:

Il modo più semplice per risolvere le inserzioni duplicate dovrebbe essere DISTINCT come il primo passo:

-- 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

Questo SQL Fiddle restituisce per i Registri duplicati data lo stesso set di risultati di SQL Fiddle , dove la query precedente viene eseguita sui dati senza duplicati.

Si prega di commentare, se e poiché ciò richiede un aggiustamento/ulteriori dettagli.