I have a MySQL 5.7 table, with time stamps on each row. My goal is to calculate the values of the some_id column and group them according to the specified 30-minute interval. And display only those intervals where count more than 0.
input:
timestamp some_id
-------------- ------
2019-01-19 05:30:12 4
2019-01-19 05:40:12 8
2019-01-19 15:37:40 2
2019-01-20 01:57:38 2
2019-01-20 07:10:07 4
2019-01-20 22:10:38 2
2019-01-21 08:35:55 4
expected:
interval COUNT(some_id)
------------- -----------
05:30:00 - 06:00:00 2
07:00:00 - 07:30:00 1
08:30:00 - 09:00:00 1
22:00:00 - 22:30:00 1
etc..........
I have tried implementing the solution presented here MySQL Group by specific 24 hour interval - but without success.
my try
I'm not sure that this is the right solution
SELECT CONCAT(
DATE_FORMAT(table.timestamp, "%H:"),
IF("30">MINUTE(table.timestamp),
(CONCAT("00-",DATE_FORMAT(DATE_ADD(table.timestamp, INTERVAL 60 MINUTE), "%H:"),"30")),
(CONCAT("30-",DATE_FORMAT(DATE_ADD(table.timestamp, INTERVAL 30 MINUTE), "%H:"),"00")))) AS time_period,
COUNT(*)
FROM table
GROUP BY time_period;
The link you provided has a very esoteric solution. Try:
SELECT CONCAT(
DATE_FORMAT(mydate, "%Y-%m-%d %H:"),
IF("30">MINUTE(mydate), "00", "30")
) AS time_bin,
COUNT(*)
FROM mytable
GROUP BY CONCAT(
DATE_FORMAT(mydate, "%Y-%m-%d %H:"),
IF("30">MINUTE(mydate), "00", "30")
)
The fastest and simplest solution would be this:
CREATE TABLE IF NOT EXISTS `events` (
`id` int unsigned NOT NULL,
`timestamp` DATETIME NOT NULL,
PRIMARY KEY (`timestamp`)
);
INSERT INTO `events` (`timestamp`, `id`) VALUES
('2019-01-19 05:30:12', 4),
('2019-01-19 06:20:12', 4),
('2019-01-19 15:37:40', 2),
('2019-01-20 01:57:38', 2),
('2019-01-20 07:10:07', 4),
('2019-01-20 22:10:38', 2),
('2019-01-21 08:35:55', 4);
And the query:
SELECT
DATE(timestamp), HOUR(timestamp), SUM(id)
FROM
events
GROUP BY 1,2 ORDER BY 1,2;
which produced
http://sqlfiddle.com/#!9/fadd28/5
EDIT: Whoops, missed the 30-minute interval requirement. But I think you get the point. You can play with my solution at the link above. :)
But if your database supports WINDOW functions, even better.
Also, for such purpose I'd personally create an aggregation table which will contain hourly counters and is being updated during INSERT using TRIGGER.
I took what #symcbean said but tunned it a bit in order to give what you wished:
SELECT CONCAT(
DATE_FORMAT(timestamp, "%H:00 - "),
IF("00">MINUTE(timestamp), CONCAT(HOUR(timestamp), ":00"), CONCAT(HOUR(timestamp), ":30"))
) AS Time,
COUNT(*)
FROM mysql_24h_cycle
GROUP BY CONCAT(
DATE_FORMAT(timestamp, "%H:"),
IF("30">MINUTE(timestamp), CONCAT(HOUR(timestamp), ":00"), CONCAT(HOUR(timestamp), ":30"))
)
Here you can see the query and the output
This is the data used
Related
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;
I have an event input of this type
event user
event start
event end
event type
Inserted to MySql table, each in its own row with user+start as primary key.
I need to query an histogram for a type by time interval (say minute) counting events occurred on each time interval.
something like:
SELECT count(*) as hits FROM events
WHERE type="browsing"
GROUP BY time_diff("2015-1-1" AND "2015-1-2") / 60 * second
but I could not find any way to do that in SQL besides writing code, any idea?
Sample data
user, start, end, type
1, 2015-1-1 12:00:00, 2015-1-1 12:03:59, browsing
2, 2015-1-1 12:03:00, 2015-1-1 12:06:00, browsing
2, 2015-1-1 12:03:00, 2015-1-1 12:06:00, eating
3, 2015-1-1 12:03:00, 2015-1-1 12:08:00, browsing
the result should look like this:
^
count |
browsing |
users | *
| * * * *
| * * * * * * * *
--|--|--|--|--|--|--|--|--|--> minute
0 1 2 3 4 5 6 7 8 9
You can do this using group by with the level that you want. Here is an example using the data you gave:
First the SQL to create the table and populate it. The ID column here isn't "needed" but it is recommended if the table will be large or have indexes on it.
CREATE TABLE `test`.`events` (
`id` INT NOT NULL AUTO_INCREMENT,
`user` INT NULL,
`start` DATETIME NULL,
`end` DATETIME NULL,
`type` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
INSERT INTO events (user, start, end, type) VALUES
(1, '2015-1-1 12:00:00', '2015-1-1 12:03:59', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'eating'),
(3, '2015-1-1 12:03:00', '2015-1-1 12:08:00', 'browsing');
To get a list of ordered pairs of number of minutes duration to number of events:
The query can then be easily written using the timestampdiff fuction, as shown below:
SELECT
TIMESTAMPDIFF(MINUTE, start, end) as minutes,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)
The output:
minutes numEvents
3 3
5 1
The first parameter in the select can be one of FRAC_SECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, or YEAR.
Here are some more examples of queries you can do:
Events by hour (floor function is applied)
SELECT
TIMESTAMPDIFF(HOUR, start, end) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
**Events by hour with better formatting **
SELECT
CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
You can group by a variety of options, but this should definitely get you started. Most plotting packages will allow you to specify arbitrary x y coordinates, so you don't need to worry about the missing values on the x axis.
To get a list of ordered pairs of number of events at a specific time (for logging):
Note that this is left for reference.
Now for the queries. First you have to pick which item you want to use for the grouping. For example, a task might take more than a minute, so the start and end would be in different minutes. For all these examples, I am basing them off of the start time, since that is when the event actually took place.
To group event counts by minute, you can use a query like this:
SELECT
DATE_FORMAT(start, '%M %e, %Y %h:%i %p') as minute,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start), MINUTE(start);
Note how this groups by all the items, starting with year, going the minute. I also have the minute displayed as a label. The resulting output looks like this:
minute numEvents
January 1, 2015 12:00 PM 1
January 1, 2015 12:03 PM 3
This is data that you could then take using php and prepare it for display by one of the many graphing libraries out there, plotting the minute column on the x axis, and plotting the numEvents on the y axis.
Here are some more examples of queries you can do:
Events by hour
SELECT
DATE_FORMAT(start, '%M %e, %Y %h %p') as hour,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start);
Events by date
SELECT
DATE_FORMAT(start, '%M %e, %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start);
Events by month
SELECT
DATE_FORMAT(start, '%M %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start);
Events by year
SELECT
DATE_FORMAT(start, '%Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start);
I should also point out that if you have an index on the start column for this table, these queries will complete quickly, even with hundreds of millions of rows.
Hope this helps! Let me know if you have any other questions about this.
I am going to assume that you have a numbers table that contains integers. You also have $starttime and $endtime.
This is one way to get the values you want:
select ($starttime + interval n.n - 1 minute) as thetime, n.n as minutes,
count(sd.user)
from numbers n left join
sampledata sd
on $starttime + interval n.n - 1 minute between sd.start and sd.end
where $starttime + interval n.n - 1 minute <= $endtime and
sd.end >= $starttime and
sd.start <= $endtime
group by n.n
order by n.n;
I want to perform a check "is there an entry for each of the last 100 days in a table" where the table has something like a reference date column and was thinking about joining with a subquery that returns sysdate - 0, sysdate - 1, ... sysdate - 100.
Updates (for clarification):
I need to know which dates are missing in the last n days
I want to avoid additional tables (also temp tables)
Is this a good approach?
Assuming your Oracle table looks like this...
CREATE TABLE DATE_TABLE (
D DATE,
-- And other fields, PK etc...
)
...and assuming D contains "round" dates (i.e. no time-of-day), the following query will give you all the missing dates between :min_date and :min_date + :day_count:
SELECT *
FROM (
SELECT (TO_DATE(:min_date) + LEVEL - 1) GENERATED_DATE
FROM DUAL
CONNECT BY LEVEL <= :day_count
)
WHERE
GENERATED_DATE NOT IN (SELECT D FROM DATE_TABLE)
In plain English:
Generate all dates in given interval (the sub-query).
Check if any of them is missing from the table (the super-query).
This is what you are looking for:
Select seqnum.date, count(issues.id)
from
(
SELECT
Curdate() - interval (TENS.SeqValue + ONES.SeqValue) day Date
FROM
(
SELECT 0 SeqValue
UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5
UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) ONES
CROSS JOIN
(
SELECT 0 SeqValue
UNION SELECT 10 UNION SELECT 20 UNION SELECT 30 UNION SELECT 40 UNION SELECT 50
UNION SELECT 60 UNION SELECT 70 UNION SELECT 80 UNION SELECT 90
) TENS
) seqnum
left join issues on (cast(issues.created_on as date) = seqnum.date)
group by seqnum.date
I ran it against a Redmine instance to see how many issues were created in the last 100 days, day by day, including days where no issue was created. Adjust to your data structures accordingly. Enjoy :)
This might help you out:
create table your_table (a_date date not null);
insert into your_table values (date(now()-interval 0 day));
insert into your_table values (date(now()-interval 1 day));
insert into your_table values (date(now()-interval 2 day));
insert into your_table values (date(now()-interval 3 day));
insert into your_table values (date(now()-interval 5 day));
insert into your_table values (date(now()-interval 6 day));
insert into your_table values (date(now()-interval 9 day));
insert into your_table values (date(now()-interval 10 day));
insert into your_table values (date(now()-interval 50 day));
insert into your_table values (date(now()-interval 60 day));
insert into your_table values (date(now()-interval 70 day));
insert into your_table values (date(now()-interval 80 day));
insert into your_table values (date(now()-interval 90 day));
select a_date,ifnull(datediff(next_date ,a_date)-1,0) as number_of_days_missing_after_date
from
(
select dt.a_date,
(select min(a_date) from your_table dtp where dtp.a_date > dt.a_date and dtp.a_date >= date(now()-interval 100 day)) as next_date
from
(select a_date
from your_table
union select date(now()-interval 100 day)) dt
where dt.a_date >= date(now()-interval 100 day)
) a;
Should give you an indication as to which dates are missing.
I have created table your_table in place of the table that you are planning to check for missing dates (so that I could illustrate my example more clearly to you).
Perhaps the only problem with this solution is that it will not give you a list of the missing dates - though they can be easily derived by looking at the (in the example) a_date column and the number of days missing after a_date.
Hope it helps & good luck!
If there aren’t any gaps (e.g., weekends), a trick you can use is
SELECT COUNT(DISTINCT somedate)=100 FROM sometable -- evaluates to boolean
WHERE somedate>=sysdate-100;
Depending on your RDBMS, a GROUP BY may work faster than COUNT DISTINCT.
[Post clarification comment]
As you have explained it now, I think you want a LEFT JOIN between a dense date list and your table, then COUNT and GROUP BY. If you are using MySQL, the way to generate the date list in a subquery is covered by this earlier stackoverflow (I don't know MySQL nearly well enough to have thought of the accepted answer). It is easier in most other DB systems.
The solution mentioned at that link of a permanent calendar table is not so bad, either.
In MySQL:
SELECT * FROM `table_name` WHERE `date_column` > DATE_SUB(CURDATE(), INTERVAL 99 DAY)
See MySQL Date Arithmetic
I have a table that looks like
expires | value
-------------------
2011-06-15 | 15
2011-06-15 | 15
2011-06-25 | 15
2011-07-15 | 15
2011-07-15 | 15
2011-07-25 | 15
2011-08-15 | 15
2011-08-15 | 15
2011-08-25 | 15
I want to run a query that will spit out
June | 45
July | 45
August | 45
So my query is
SELECT SUM(amount) AS `amount`,
DATE_FORMAT(expires , '%M') AS `month`
FROM dealDollars
WHERE DATE(expires) BETWEEN DATE(NOW())
AND LAST_DAY(DATE(NOW()+INTERVAL 3 MONTH))
GROUP BY MONTH(expires)
Which works fine. But with the result, if there were no rows in say July, July would not show up.
How can I force July to show up with 0 as its value?
There is no easy way to do this. One possible way is to have a table called months:
Which will have 12 rows: (January, February, ..., December)
You can left join the Months table with the query you have to get the desired output.
The general consensus is that you should just create a table of month names. What follows is a silly solution which can serve as a workaround.
You'll have to work on the specifics yourself, but have you looked at sub-queries in the from clause?
Basically, it would be something like this:
SELECT NVL(B.amount, 0) as `amount`, A.month as `month`
FROM (SELECT 'January' as `month`
UNION SELECT 'February' as `month`
UNION SELECT 'March' as `month`...
UNION SELECT 'DECEMBER' as `month`) as A
LEFT JOIN
(SELECT SUM(amount) AS `amount`,
DATE_FORMAT(expires , '%M') AS `month`
FROM dealDollars
WHERE
DATE(expires) BETWEEN
DATE(NOW()) AND
LAST_DAY(DATE(NOW()+INTERVAL 3 MONTH))
GROUP BY MONTH(expires)) as B
ON (A.MONTH = B.MONTH)
Crazy, no?
MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -
Create a table that only holds incrementing numbers - easy to do using an auto_increment:
DROP TABLE IF EXISTS `example`.`numbers`;
CREATE TABLE `example`.`numbers` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Populate the table using:
INSERT INTO NUMBERS
(id)
VALUES
(NULL)
...for as many values as you need. In this case, the INSERT statement needs to be run at least 3 times.
Use DATE_ADD to construct a list of days, increasing based on the NUMBERS.id value:
SELECT x.dt
FROM (SELECT DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) AS dt
FROM numbers n
WHERE DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) BETWEEN CURRENT_DATE()
AND LAST_DAY(CURRENT_DATE() +INTERVAL 3 MONTH)) ) x
Use an OUTER JOIN to get your desired output:
SELECT x.dt,
COUNT(*) AS total
FROM (SELECT DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) AS dt
FROM numbers n
WHERE DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) BETWEEN CURRENT_DATE()
AND LAST_DAY(CURRENT_DATE() +INTERVAL 3 MONTH)) ) x
LEFT JOIN YOUR_TABLE y ON y.date = x.dt
GROUP BY x.dt
ORDER BY x.dt
Why Numbers, not Dates?
Simple - dates can be generated based on the number, like in the example I provided. It also means using a single table, vs say one per data type.
select MONTHNAME(expires) as month_name,sum(`value`) from Table1
group by month_name order by null;
fiddle
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;