Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Suma czasu trwania według zmiany lokalizacji

Wydaje się, że to wystarczy:

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
;

Zobacz w akcji:SQL Fiddle .

Aktualizacja:

Jeśli chcesz dołączyć do dodatkowych stołów, powinieneś właściwie JOIN a nie podwybór. Ponieważ istnieje GROUP BY na obecnym skrajnym poziomie istniejąca instrukcja musi być otoczona innym zestawem nawiasów — aby zapobiec grupowaniu się nad tabelami faktów. Z kilkoma innymi zmianami w tym celu:

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
;

Rozszerzone SQL Fiddle .

Aktualizacja 2:

Najprostszym sposobem rozwiązania problemu zduplikowanych wpisów powinno być DISTINCT je odejść jako pierwszy krok:

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

To SQL Fiddle zwraca dla zduplikowanych Dzienników dane ten sam zestaw wyników, co SQL Fiddle , gdzie wcześniejsze zapytanie działa na danych bez duplikatów.

Proszę o komentarz, jeśli i jak wymaga to korekty / dalszych szczegółów.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Porządkowanie liczb całkowitych w wielu kolumnach

  2. Hibernacja:nie można wykonać natywnego zapytania do manipulacji zbiorczej

  3. Czy są jakieś dobre implementacje CachedRowSet inne niż zastrzeżona Sun?

  4. Jak wyłączyć buforowanie SQLAlchemy?

  5. Wyszukiwanie wyrażeń regularnych Mysql bez powtarzających się znaków