简体   繁体   中英

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

I have a table with these two columns (plus some others that are not relevant):

transaction_pk and value_timestamp

I would like to get the time difference (in minutes) for each transaction_pk. Each transaction_pk has many rows and i'm not looking for difference between 1st and last timestamp

Example 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

The desired output would look like this:

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

I have tried the following question:

Calculate the difference in minutes between timestamp mysql

but I get the following error message when I try and execute the code

#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'report_db.x.connector_pk' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

*Edit - this now works after running the following:

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

It does however take a long time to run. Is there a way to make it quicker and also to update my table rather than just run a query.

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

I'm not a fan of putting subqueries in the SELECT but it's a way of solving this problem for ancient versions of 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

You can use it like you would any other value in eg a call to 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

The COALESCE converts the NULL that results from the first value per PK not having any "timestamp less than the current", into a 0.. otherwise, the idea of diffing on the seconds then dividing by 60 gives us a decimal representation of the number of fractional minutes since the previous time. If you need greater precision, use a smaller time interval and a greater divisor respectively

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM