计算来自同一列的时间戳之间的时间差(以分钟为单位)mysql

calculate time difference in minutes between timestamp from the same column mysql

我有一个 table 包含这两列(加上一些不相关的其他列):

transaction_pk 和 value_timestamp

我想得到每个 transaction_pk 的时差(以分钟为单位)。每个 transaction_pk 都有很多行,我不是在寻找第一个和最后一个时间戳之间的差异

示例table

transaction_pk    |   status_timestamp
1                 |   2020-02-11 19:14:45
1                 |   2020-02-11 19:18:45
1                 |   2020-02-11 19:15:45
2                 |   2020-02-11 19:18:45
2                 |   2020-02-11 19:14:45
2                 |   2020-02-11 19:19:45

所需的输出如下所示:

transaction_pk    |   status_timestamp     | time_diff
1                 |   2020-02-11 19:14:45  | 0
1                 |   2020-02-11 19:18:45  | 04:00
1                 |   2020-02-11 19:20:45  | 02:00
2                 |   2020-02-11 19:18:45  | 0
2                 |   2020-02-11 19:14:45  | 04:00
2                 |   2020-02-11 19:19:45  | 05:00

我试过以下问题:

Calculate the difference in minutes between timestamp mysql

但是当我尝试执行代码时收到以下错误消息

#1055 - SELECT 列表的表达式 #1 不在 GROUP BY 子句中并且包含非聚合列 'report_db.x.connector_pk',它在功能上不依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by

不兼容

*编辑 - 这现在在 运行 执行以下操作后有效:

设置全局sql_mode=(SELECT替换(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

然而 运行 确实需要很长时间。有没有办法让它更快并更新我的 table 而不仅仅是 运行 一个查询。

SELECT t1.transaction_pk, 
       t1.status_timestamp,
       COALESCE(TIMESTAMPDIFF(MINUTE, t2.status_timestamp, t1.status_timestamp), 0) time_diff
FROM test t1
LEFT JOIN test t2 ON t1.transaction_pk = t2.transaction_pk
                 AND t1.status_timestamp > t2.status_timestamp
WHERE NOT EXISTS ( SELECT NULL
                   FROM test t3
                   WHERE t1.transaction_pk = t3.transaction_pk
                     AND t1.status_timestamp > t3.status_timestamp
                     AND t3.status_timestamp > t2.status_timestamp )

fiddle

我不喜欢在 SELECT 中放置子查询,但这是解决 MySQL 旧版本问题的一种方法:

SELECT 
  transaction_pk,
  status_timestamp,
  (SELECT MAX(tsub.status_timestamp) FROM t tsub WHERE tsub.transaction_pk = tmain.transaction_pk and tsub.status_timestamp < tmain.status_timestamp) as last_timestamp
FROM
  t tmain

您可以像使用任何其他值一样使用它,例如调用 timestampdiff:

SELECT 
  transaction_pk,
  status_timestamp,
  COALESCE(TIMESTAMPDIFF(
    SECOND,
    (SELECT MAX(tsub.status_timestamp) FROM test tsub WHERE tsub.transaction_pk = tmain.transaction_pk and tsub.status_timestamp < tmain.status_timestamp),
    status_timestamp
  )/60.0, 0) as diff
FROM
  t tmain

COALESCE 将每个 PK 的第一个值没有任何“小于当前时间戳”的值所产生的 NULL 转换为 0.. 否则,在秒上进行差异然后除以 60 的想法给了我们一个自上次以来的小数分钟数的十进制表示。如果需要更高的精度,分别使用更小的时间间隔和更大的除数