按位置更改的总时间

时间:2015-07-15 22:01:53

标签: mysql sql

我有一个现有的MySQL查询(我是新手所以请保持温和),我需要修改但是我很难确定所需的更改 -

SELECT assetid, locationid, ts,    
  TIMESTAMPDIFF(SECOND,    
    (SELECT MAX(ts) FROM logs WHERE ts< t.ts),
    ts
  ) secdiff
FROM logs t    
where assetid = 1157    
order by ts DESC

返回(正确)

id   location    datetime       time difference (between rows)    
1157    1   2015-07-02 10:21:56 2    
1157    1   2015-07-02 10:21:54 2    
1157    2   2015-07-02 10:21:52 2    
1157    2   2015-07-02 10:21:50 2    
1157    2   2015-07-02 10:21:48 2    
1157    1   2015-07-02 10:21:46 2    
1157    1   2015-07-02 10:21:44 6    
1157    1   2015-07-02 10:21:38 2

我需要能够确定在每个位置花费的总持续时间(位置可以是除1和2之外的其他数字),但不按位置分组,而是用/分隔,直到每个位置发生变化。行之间的时间会有所不同(并非总是2秒)。 assetid将根据主查询而改变。

结果将是(对于assetid 1157):

id        location  duration
1157        1         4
1157        2         6
1157        1         8

1 个答案:

答案 0 :(得分:0)

以下似乎可以解决问题:

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
;

查看实际操作:SQL Fiddle

<强>更新

如果您需要加入其他表,则实际上应该JOIN而不是子选择。由于当前最高级别存在GROUP BY,因此现有语句需要包含在另一组括号中 - 以防止对事实表进行分组。对此进行了一些其他调整:

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

更新2:

解决重复列表的最简单方法应该是DISTINCT将其作为第一步:

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

SQL Fiddle会将重复的日志数据返回与SQL Fiddle相同的结果集,其中较早的查询针对没有重复项的数据运行。

如果需要调整/进一步详细说明,请发表评论。