sql >> Base de Datos >  >> RDS >> Mysql

Sumar la duración del tiempo por cambio de ubicación

Lo siguiente parece funcionar:

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
;

Véalo en acción:SQL Fiddle .

Actualización:

Si necesita unirse a mesas adicionales, debería JOIN y no sub-seleccionar. Como hay un GROUP BY en el nivel más externo actualmente, la declaración existente debe estar envuelta en otro conjunto de paréntesis, para evitar la agrupación en las tablas de hechos. Con algunos otros ajustes hacia ese fin:

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

Actualización 2:

La forma más sencilla de abordar los listados duplicados debería ser DISTINCT como primer paso:

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

Este SQL Fiddle devoluciones para los Registros duplicados data el mismo conjunto de resultados que SQL Fiddle , donde la consulta anterior se ejecuta en datos sin duplicados.

Por favor comente, si y como esto requiere ajuste/más detalles.