Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between dates in two consecutive rows

+----------+--------------+-------------------------+
| ticketid | ticketpostid |           date          |
+----------+--------------+-------------------------+
|  1387935 |      3147808 | 2012-09-17 13:33:01     |
|  1387935 |      3147812 | 2012-09-17 13:33:41     |
|  1387938 |      3147818 | 2012-09-17 13:35:01     |
|  1387938 |      3148068 | 2012-09-17 13:37:01     |
|  1387938 |      3148323 | 2012-09-17 14:47:01     |
|  1387939 |      3147820 | 2012-09-17 13:36:01     |
|  1387939 |      3147834 | 2012-09-17 13:36:25     |
|  1387939 |      3147851 | 2012-09-17 13:41:01     |
|  1387939 |      3147968 | 2012-09-17 13:59:06     |
|  1387939 |      3147996 | 2012-09-17 14:03:01     |

This is a result of a query that I wrote. There are two and more than two rows with same ticketid. I need to find the time difference between first two date in each ticketid

Ex.

+----------+--------------+-------------------------+
| ticketid | ticketpostid |           date          |
+----------+--------------+-------------------------+
|  1387935 |      3147808 | 2012-09-17 13:33:01     |
|  1387935 |      3147812 | 2012-09-17 13:33:41     |
|  1387938 |      3147818 | 2012-09-17 13:35:01     |
|  1387938 |      3148068 | 2012-09-17 13:37:01     |
|  1387939 |      3147820 | 2012-09-17 13:36:01     |
|  1387939 |      3147834 | 2012-09-17 13:36:25     |

As a result;

+----------+--------------+
| ticketid |time diff(sec)|
+----------+--------------+
|  1387935 |      40      |
|  1387938 |      120     |
|  1387939 |      24      |

Can you tell me how I can do this?

Thanks.

like image 366
TraviJuu Avatar asked Sep 17 '12 12:09

TraviJuu


People also ask

How do you find the difference between two consecutive rows in SQL?

In the blue text, you can see the calculation of the SQL delta between two rows. To calculate a difference, you need a pair of records; those two records are “the current record” and “the previous year's record”. You obtain this record using the LAG() window function.

How do I get the difference between two dates in SQL?

The DATEDIFF() function returns the difference between two dates.

How can I compare two rows in the same table in SQL?

Example 1: Comparing rows of the same table. In the example, we are comparing the immediate rows to calculate the sales made on a day by comparing the amounts of two consecutive days. Syntax for inner join : SELECT column_name(s) FROM table1 t1 INNER JOIN table1 t2 on t1. column1 = t2.


2 Answers

For PostgreSQL, I think you want the lag window function to compare the rows; it'll be much more efficient than a self-join and filter. This won't work with MySQL, as it still doesn't seem to support the standard SQL:2003 window functions; see below.

To find only the two lowest you can use the dense_rank window function over the ticketid, then filter the results to return only rows where dense_rank() = 2, ie row with the second-from-lowest timestamp, where lag() will produce the row with the lowest timestamp.

See this SQLFiddle which shows sample DDL and output.

SELECT ticketid, extract(epoch from tdiff) FROM (
  SELECT
      ticketid,
      ticketdate - lag(ticketdate) OVER (PARTITION BY ticketid ORDER BY ticketdate) AS tdiff,
      dense_rank() OVER (PARTITION BY ticketid ORDER BY ticketdate) AS rank
  FROM Table1
  ORDER BY ticketid) x
WHERE rank = 2;

I've used ticketdate as the name for the date column because date is a terrible name for a column (it's a data type name) and should never be used; it has to be double quoted in many situations to work.

The portable approach is probably the self-join others have posted. The window function approach above probably works on Oracle too, but doesn't seem to in MySQL. As far as I can find out it doesn't support the SQL:2003 window functions.

The schema definition will work with MySQL if you SET sql_mode = 'ANSI' and use timestamp instead of timestamp with time zone. It seems the window functions won't; MySQL chokes on the OVER clause. See this SQLFiddle.

like image 134
Craig Ringer Avatar answered Sep 21 '22 18:09

Craig Ringer


Try this query -

INSERT INTO ticket_post(ticketid, ticketpostid, date) VALUES
(1387935, 3147808, '2012-09-17 13:33:01'),
(1387935, 3147812, '2012-09-17 13:33:41'),
(1387938, 3147818, '2012-09-17 13:35:01'),
(1387938, 3148068, '2012-09-17 13:37:01'),
(1387938, 3148323, '2012-09-17 14:47:01'),
(1387939, 3147820, '2012-09-17 13:36:01'),
(1387939, 3147834, '2012-09-17 13:36:25'),
(1387939, 3147851, '2012-09-17 13:41:01'),
(1387939, 3147968, '2012-09-17 13:59:06'),
(1387939, 3147996, '2012-09-17 14:03:01');

SELECT
  ticketid,
  TIME_TO_SEC(TIMEDIFF((
    SELECT t.date FROM ticket_post t WHERE t.ticketid = t1.ticketid AND t.date > t1.date ORDER BY t.date LIMIT 1),
    MIN(date)
  )) diff FROM ticket_post t1
GROUP BY ticketid;

+----------+------+
| ticketid | diff |
+----------+------+
|  1387935 |   40 |
|  1387938 |  120 |
|  1387939 |   24 |
+----------+------+
like image 45
Devart Avatar answered Sep 24 '22 18:09

Devart