Grouping timestamp every 30 minutes - mysql

I'm trying to group my timestamp every 30 minutes.
I want my result to be like this:
2016-03-09 00:00:00
2016-03-09 00:30:00
2016-03-09 01:00:00
Instead, my results are this:
2016-03-09 00:00:23
2016-03-09 00:35:02
2016-03-09 01:00:03
The query that I'm using is this
SELECT timestamp
FROM a.tablename
WHERE name = 'example' AND timestamp LIKE '2016-03-09%'
GROUP BY ROUND(((60/30) * HOUR(timestamp) + FLOOR( MINUTE(timestamp) / 30)));
How can I have my desired results? I've researched other answers on SO and non of the answers helped

Here's the basic query to group by 30 minutes interval.
SELECT
FROM_UNIXTIME(ROUND(UNIX_TIMESTAMP(timestamp)/(30* 60)) * (30*60)) thirtyHourInterval
FROM tablename
GROUP BY ROUND(UNIX_TIMESTAMP(timestamp)/(30* 60));
Note: ROUND() may lead you towards wrong output. Use the following query instead. Look at the following example:
SELECT ROUND(3.7), ROUND(4.2);
Result: 4 4.
Both lies in the same segment. The same holds for the above query while rounding the timestamp of different segments might fall in the same segment thus leading towards wrong output
[The following query is Recommended]
SELECT
FROM_UNIXTIME((UNIX_TIMESTAMP(`timestamp`) DIV (30* 60) ) * (30*60)) thirtyHourInterval
FROM tablename
GROUP BY UNIX_TIMESTAMP(`timestamp`) DIV (30* 60)
SQL FIDDLE DEMO
Alternatively you can adopt the following query.
SELECT
FROM_UNIXTIME(ROUND(UNIX_TIMESTAMP(timestamp)/(30* 60)) * (30*60)) thirtyHourInterval
FROM tablename
GROUP BY ( 4 * HOUR( `timestamp` ) + FLOOR( MINUTE( `timestamp` ) / 30 ));
Relatedpost

One method is to use to_seconds(), truncate the value, and then re-create the datetime value:
select date_add(0, interval floor(to_seconds(timestamp) / (30 * 60)) second) as timestamp
from a.tablename
where name = 'example' and timestamp >= '2016-03-09' and timestamp < '2016-03-10'
group by date_add(0, interval floor(to_seconds(timestamp) / (30 * 60)) second)
order by 1;

Related

SELECT to count events by intervals [duplicate]

I've got a monitoring system that is collecting data every n seconds (n is approximately 10 but varies). I'd like to aggregate the collected data by 15 minute intervals. Is there a way to consolidate the timestamp values into 15 minute chunks to allow for grouping to work?
SELECT FLOOR(UNIX_TIMESTAMP(timestamp)/(15 * 60)) AS timekey
FROM table
GROUP BY timekey;
Try this , grouping of records of 15 minutes interval, you can change 15*60 to the interval in seconds you need
SELECT sec_to_time(time_to_sec(datefield)- time_to_sec(datefield)%(15*60)) as intervals from tablename
group by intervals
Adaptation of approach 1) below:
select Round(date_format(date, "%i") / (15*60)) AS interval
from table
group by interval
Adaptation of approach 3) below:
SELECT Round(Convert(substring(date_column, 14, 2), UNSIGNED) / (15*60)) AS interval /* e.g. 2009-01-04 12:20:00 */
FROM table
GROUP BY interval;
A few approaches I've found here:
1)
select date_format(date, "%W") AS `Day of the week`, sum(cost)
from daily_cost
group by `Day of the week`
order by date_format(date, "%w")
2)
select count(*) as 'count',
date_format(min(added_on), '%Y-%M-%d') as 'week commencing',
date_format(added_on, '%Y%u') as 'week'
from system
where added_on >= '2007-05-16'
group by week
order by 3 desc;
3)
SELECT substring(postdate, 1,10) AS dd, COUNT(id) FROM MyTable GROUP BY dd;
(Also here: http://www.bradino.com/mysql/dayparting-on-datetime-field-using-substring/)
EDIT: All the solutions will perform badly on a table with a large number of records.
I started with the answer given above by unutbu but didn't get what I needed and had to add a bit to it.
Select Created, from_unixtime(FLOOR(UNIX_TIMESTAMP(Created)/(15*60))*(15*60)) GroupTime,
COUNT(*) as Cnt
FROM issue i
GROUP BY GroupTime
This code divides by the 900 seconds in a 15 minute span then floors the value and multiplies it back up by 900, essentially rounding down to the nearest 15 minute increment.
Following query groups rows and creates timestamps at 15 min intervals.
Select concat( date(created_dt) , ' ', sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))as created_dt_new from table_name group by created_dt_new
E.g Timestamps
2016-11-09 13:16:29
2016-11-09 13:16:49
2016-11-09 13:17:06
2016-11-09 13:17:26
2016-11-09 13:18:24
2016-11-09 13:19:59
2016-11-09 13:21:17
Are grouped into 2016-11-09 13:30:00
sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))
Upper bounds time to nearest 15 min interval. e.g 12:10 -> 12:15
concat( date(created_dt) , ' ', sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))
Generates a timestamp taking the date from the timestamp field.
Unix timestamps: floor them to nearest 15 minute using one of the following:
timestamp div (15 * 60) * (15 * 60) -- div is integer division operator
timestamp - timestamp % (15 * 60)
Date time: assuming the datatype does not have fractional seconds, floor them to nearest 15 minute using:
date - INTERVAL EXTRACT(SECOND FROM date) SECOND - INTERVAL EXTRACT(MINUTE FROM date) % 15 MINUTE
DBFiddle
This worked for me
mysql> **SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(NOW())- UNIX_TIMESTAMP(NOW())%(15*60));**
+---------------------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP(NOW())- UNIX_TIMESTAMP(NOW())%(15*60)) |
+---------------------------------------------------------------------+
| 2012-02-09 11:15:00 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
THis Work for me
SELECT CONCAT (
YEAR(transactionDate)
,'-'
,MONTH(transactionDate)
,'-'
,DAYOFMONTH(transactionDate)
,' '
,HOUR(transactionDate)
,':'
,((floor((MINUTE(transactionDate) / 15)) + 1) * 15) - 1
,':59'
) AS tmp1
,count(*)
FROM tablename
GROUP BY tmp1 limit 20;
Change "15" to whatever interval you want.
select count(*),
CONCAT(HOUR(col_date),":",(MINUTE(create_date) div 15)*15) as date
from tablename
GROUP BY date
ORDER BY col_date ASC;
I was not satisfied by GROUP BY.
SELECT datetime
FROM table
WHERE MOD(MINUTE(TIME(datetime)),15) = 0 AND SECOND(TIME(datetime)) = 0;

mysql according to time interval query data

I have the following MySQL table:
My requirements are,At a 30-minute time interval query data,with no need for group by,This concept,For the first time encounter this kind of question,How can I achieve that effect,The interval between the last one and the next is 30 minutes
I think this does what you want:
select t.*
from t
where t.time = (select min(t2.time)
from t t2
where floor(to_seconds(t2.time) / (30 * 60)) = floor(to_seconds(t.time) / (30 * 60))
);
the other day think of answer:
SELECT FROM_
UNIXTIME(UNIX_TIMESTAMP(t.Time)- UNIX_TIMESTAMP(t.Time)%(15*60))
AS timekey,DB33,Stream,`View`,Coil
FROM (select DB33,Stream,`View`,Time,Coil from running_check where
DB33=#{DB33} ORDER BY id desc limit 10000) as t
GROUP BY timekey

SQL Query by created 3 hours ago

Given a set of data with date_created stored like 2017-04-13 23:29:52, how would I construct an SQL query to select all items that were created within the last 3 hours?
I originally thought to do something like this:
SELECT
*,
MAX(date_created)
FROM items
GROUP BY date_created
but that would not be exactly what I want. I'm not sure how to go about this.
Use NOW() and INTERVAL in your WHERE clause
SELECT * FROM items WHERE date_created <= NOW() - INTERVAL 180 minute AND date_created >= NOW() - INTERVAL 210 minute
This one uses CURDATE, CURDATE and DATE_ADD:
SELECT *
FROM items
WHERE DATE(date_created) = CURDATE()
AND TIME(date_created) BETWEEN CURTIME() AND DATE_ADD(CURTIME(), INTERVAL -3 HOUR)
select * from items where
extract(hours from age(current_timestamp, date_created))>=3;
Extract keyword would extract hours difference from current timestamp and return only that is greater than or equal to 3.

Query to select record of last five days but in between a specific time

I need to select rows from mdl_logstore_standard_log, the condition is timecreated should be in between last five days 7.30 AM to 4.30PM. How can I achive the combination last 5 days and the time. This is what I have
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= DATE_SUB(CURDATE(), INTERVAL 5 DAY)
GROUP by userid
timecreated is in unixtimestamp
You can do this way too
SELECT
*
FROM mdl_logstore_standard_log
WHERE timecreated >= UNIX_TIMESTAMP(CURDATE() - INTERVAL 5 DAY)
AND (
(timecreated % 86400)
BETWEEN UNIX_TIMESTAMP('1970-01-01 07:30')
AND UNIX_TIMESTAMP('1970-01-01 16:30')
)
GROUP by userid
timecreated % 86400 would return the residue in seconds.
And if the residue lies between 1970-01-01 07:30 and 1970-01-01 16:30 then your condition is actually met.
Note:
Using GROUP BY without aggregate function is discouraged.
(#scaisEdge already stated that)
If you approach this way you take advantage from index on
timecreated field (if any)
PLS try this
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= FROM_UNIXTIME(DATE_SUB(CURDATE(), INTERVAL 5 DAY))
GROUP by userid;
You could use time
SELECT * FROM mdl_logstore_standard_log
WHERE FROM_UNIXTIME(timecreated) >= DATE_SUB(CURDATE(), INTERVAL 5 DAY)
AND time(FROM_UNIXTIME(timecreated))
between time('2016-01-01 07:30:00.0000' ) and time('2016-01-01 16:30:00.0000' )
GROUP by userid
NB you are using group by without aggregation function .. this could retrive not coherent result ..

Group mysql query by 15 min intervals

I've got a monitoring system that is collecting data every n seconds (n is approximately 10 but varies). I'd like to aggregate the collected data by 15 minute intervals. Is there a way to consolidate the timestamp values into 15 minute chunks to allow for grouping to work?
SELECT FLOOR(UNIX_TIMESTAMP(timestamp)/(15 * 60)) AS timekey
FROM table
GROUP BY timekey;
Try this , grouping of records of 15 minutes interval, you can change 15*60 to the interval in seconds you need
SELECT sec_to_time(time_to_sec(datefield)- time_to_sec(datefield)%(15*60)) as intervals from tablename
group by intervals
Adaptation of approach 1) below:
select Round(date_format(date, "%i") / (15*60)) AS interval
from table
group by interval
Adaptation of approach 3) below:
SELECT Round(Convert(substring(date_column, 14, 2), UNSIGNED) / (15*60)) AS interval /* e.g. 2009-01-04 12:20:00 */
FROM table
GROUP BY interval;
A few approaches I've found here:
1)
select date_format(date, "%W") AS `Day of the week`, sum(cost)
from daily_cost
group by `Day of the week`
order by date_format(date, "%w")
2)
select count(*) as 'count',
date_format(min(added_on), '%Y-%M-%d') as 'week commencing',
date_format(added_on, '%Y%u') as 'week'
from system
where added_on >= '2007-05-16'
group by week
order by 3 desc;
3)
SELECT substring(postdate, 1,10) AS dd, COUNT(id) FROM MyTable GROUP BY dd;
(Also here: http://www.bradino.com/mysql/dayparting-on-datetime-field-using-substring/)
EDIT: All the solutions will perform badly on a table with a large number of records.
I started with the answer given above by unutbu but didn't get what I needed and had to add a bit to it.
Select Created, from_unixtime(FLOOR(UNIX_TIMESTAMP(Created)/(15*60))*(15*60)) GroupTime,
COUNT(*) as Cnt
FROM issue i
GROUP BY GroupTime
This code divides by the 900 seconds in a 15 minute span then floors the value and multiplies it back up by 900, essentially rounding down to the nearest 15 minute increment.
Following query groups rows and creates timestamps at 15 min intervals.
Select concat( date(created_dt) , ' ', sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))as created_dt_new from table_name group by created_dt_new
E.g Timestamps
2016-11-09 13:16:29
2016-11-09 13:16:49
2016-11-09 13:17:06
2016-11-09 13:17:26
2016-11-09 13:18:24
2016-11-09 13:19:59
2016-11-09 13:21:17
Are grouped into 2016-11-09 13:30:00
sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))
Upper bounds time to nearest 15 min interval. e.g 12:10 -> 12:15
concat( date(created_dt) , ' ', sec_to_time(time_to_sec(created_dt)- time_to_sec(created_dt)%(15*60) + (15*60)))
Generates a timestamp taking the date from the timestamp field.
Unix timestamps: floor them to nearest 15 minute using one of the following:
timestamp div (15 * 60) * (15 * 60) -- div is integer division operator
timestamp - timestamp % (15 * 60)
Date time: assuming the datatype does not have fractional seconds, floor them to nearest 15 minute using:
date - INTERVAL EXTRACT(SECOND FROM date) SECOND - INTERVAL EXTRACT(MINUTE FROM date) % 15 MINUTE
DBFiddle
This worked for me
mysql> **SELECT FROM_UNIXTIME(UNIX_TIMESTAMP(NOW())- UNIX_TIMESTAMP(NOW())%(15*60));**
+---------------------------------------------------------------------+
| FROM_UNIXTIME(UNIX_TIMESTAMP(NOW())- UNIX_TIMESTAMP(NOW())%(15*60)) |
+---------------------------------------------------------------------+
| 2012-02-09 11:15:00 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
THis Work for me
SELECT CONCAT (
YEAR(transactionDate)
,'-'
,MONTH(transactionDate)
,'-'
,DAYOFMONTH(transactionDate)
,' '
,HOUR(transactionDate)
,':'
,((floor((MINUTE(transactionDate) / 15)) + 1) * 15) - 1
,':59'
) AS tmp1
,count(*)
FROM tablename
GROUP BY tmp1 limit 20;
Change "15" to whatever interval you want.
select count(*),
CONCAT(HOUR(col_date),":",(MINUTE(create_date) div 15)*15) as date
from tablename
GROUP BY date
ORDER BY col_date ASC;
I was not satisfied by GROUP BY.
SELECT datetime
FROM table
WHERE MOD(MINUTE(TIME(datetime)),15) = 0 AND SECOND(TIME(datetime)) = 0;