sql >> Database >  >> RDS >> Mysql

Som tijdsduur per locatiewijziging

Het volgende lijkt te werken:

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
;

Zie het in actie:SQL Fiddle .

Bijwerken:

Als je aan extra tabellen moet deelnemen, moet je eigenlijk JOIN en niet subselecteren. Omdat er een GROUP BY . is op het huidige hoogste niveau moet de bestaande verklaring tussen een andere set haakjes worden gewikkeld - om te voorkomen dat de feitentabellen worden gegroepeerd. Met wat andere aanpassingen in die richting:

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
;

Uitgevouwen SQL Fiddle .

Update 2:

De eenvoudigste manier om dubbele vermeldingen aan te pakken, is door DISTINCT . te gebruiken ze weg als de allereerste stap:

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

Deze SQL Fiddle retourneert voor de gedupliceerde Logs data hetzelfde resultaat ingesteld als SQL Fiddle , waarbij de eerdere zoekopdracht wordt uitgevoerd op gegevens zonder duplicaten.

Gelieve commentaar te geven, indien en als dit aanpassing / verdere details vereist.




  1. SQL Server Hoge beschikbaarheid:SQL Server failover geclusterd exemplaar installeren, deel 2

  2. Hoe een tweede vervolgkeuzelijst te tonen op basis van de vorige vervolgkeuzelijst met Javascript

  3. Hibernate @OneToMany genereert MySQLSyntaxErrorException:er is een fout opgetreden in uw SQL-syntaxis

  4. Rails ActiveRecord - is er een manier om bewerkingen uit te voeren op tabellen zonder een id?