Reputation: 43
This is what I have so far
SELECT messageDatestamp
, count(messageDatestamp)
From table
where messageDatestamp between '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)
group
by UNIX_TIMESTAMP(messageDatestamp)
ORDER
BY messageDatestamp asc;
messageDatestamp Column data
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:43
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:44
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45
2019-01-01 07:25:45
Output
2019-01-01 07:25:43, 6
2019-01-01 07:25:44, 11
2019-01-01 07:25:45, 12
I don't want to execute a select statement for each daterange where the end date is increment every one second like the example below.
between '2019-01-01 07:25:42' and '2019-01-01 07:26:43'
between '2019-01-01 07:25:42' and '2019-01-01 07:26:44'
between '2019-01-01 07:25:42' and '2019-01-01 07:26:45'
Is there a way to increment the end date or add the previous count value using one query?
This is what I would like the MySQL to output.
2019-01-01 07:25:43, 6 (Count is between 07:25:42 and 07:25:43)
2019-01-01 07:25:44, 17 (Count is between 07:25:42 and 07:25:44)
2019-01-01 07:25:45, 22 (Count is between 07:25:42 and 07:25:45)
Upvotes: 1
Views: 94
Reputation: 1270463
Is there a way to increment the end date or add the previous count value using one query?
You can use lag()
:
SELECT MIN(messageDatestamp), COUNT(*),
(COUNT(*) + LAG(COUNT(*), 1, 0) OVER (ORDER BY MIN(messageDatestamp))
) as cnt_2
FROM table
WHERE messageDatestamp BETWEEN '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)
GROUP BY UNIX_TIMESTAMP(messageDatestamp)
ORDER BY messageDatestamp asc;
EDIT:
I see, I misunderstood your question. You simply want a cumulative count:
You can use lag()
:
SELECT MIN(messageDatestamp), COUNT(*),
SUM(COUNT(*))OVER (ORDER BY MIN(messageDatestamp)) as cnt_2
FROM table
WHERE messageDatestamp BETWEEN '2019-01-01 07:25:42' AND date_add('2019-01-01 07:25:45' , INTERVAL 1 SECOND)
GROUP BY UNIX_TIMESTAMP(messageDatestamp)
ORDER BY messageDatestamp asc;
Upvotes: 1
Reputation: 29667
In MySql 8.0 one can SUM OVER a normal COUNT.
With an ORDER BY that SUM OVER will calculate a cumulative total.
If the messageDatestamp is a TIMESTAMP(6)
then to compare it could be truncated to the seconds.
SELECT DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s') AS messageDatestamp
,SUM(COUNT(*)) OVER (ORDER BY DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s')) AS CumulativeCount
FROM `table` t
WHERE messageDatestamp >= TIMESTAMP('2019-01-01 07:25:42')
AND messageDatestamp < TIMESTAMP('2019-01-01 07:25:45','00:00:01')
GROUP BY DATE_FORMAT(messageDatestamp,'%Y-%m-%d %H:%i:%s')
ORDER BY messageDatestamp ASC;
Using DATE_FORMAT here to truncate the timestamp to seconds.
Since UNIX_TIMESTAMP might cause a problem in the year 2038.
UPDATE
If messageDatestamp
is a DATETIME(0)
then it doesn't need to be truncated to the seconds.
Then the SQL can be golf-coded.
SELECT messageDatestamp
,SUM(COUNT(*)) OVER (ORDER BY messageDatestamp) AS CumulativeCount
FROM `table` t
WHERE messageDatestamp >= '2019-01-01 07:25:42'
AND messageDatestamp <= '2019-01-01 07:25:45'
GROUP BY messageDatestamp
ORDER BY messageDatestamp ASC;
A test on db<>fiddle here
Upvotes: 1