可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have some difficulties with mySQL commands that I want to do.
SELECT a.timestamp, name, count(b.name)
FROM time a, id b
WHERE a.user = b.user
AND a.id = b.id
AND b.name = \'John\'
AND a.timestamp BETWEEN \'2010-11-16 10:30:00\' AND \'2010-11-16 11:00:00\'
GROUP BY a.timestamp
This is my current output statement.
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:32:22 John 2
2010-11-16 10:35:12 John 7
2010-11-16 10:36:34 John 1
2010-11-16 10:37:45 John 2
2010-11-16 10:48:26 John 8
2010-11-16 10:55:00 John 9
2010-11-16 10:58:08 John 2
How do I group them into 5 minutes interval results?
I want my output to be like
timestamp name count(b.name)
------------------- ---- -------------
2010-11-16 10:30:00 John 2
2010-11-16 10:35:00 John 10
2010-11-16 10:40:00 John 0
2010-11-16 10:45:00 John 8
2010-11-16 10:50:00 John 0
2010-11-16 10:55:00 John 11
回答1:
This works with every interval.
PostgreSQL
SELECT
TIMESTAMP WITH TIME ZONE \'epoch\' +
INTERVAL \'1 second\' * round(extract(\'epoch\' from timestamp) / 300) * 300,
as timestamp,
name,
count(b.name)
FROM time a, id
WHERE …
GROUP BY
round(extract(\'epoch\' from timestamp) / 300), name
MySQL
SELECT
timestamp, -- not sure about that
name,
count(b.name)
FROM time a, id
WHERE …
GROUP BY
UNIX_TIMESTAMP(timestamp) DIV 300, name
回答2:
You should rather use GROUP BY UNIX_TIMESTAMP(time_stamp) DIV 300
instead of round(../300) because of the rounding I found that some records are counted into two grouped result sets.
回答3:
For postgres, I found it easier and more accurate to use the
date_trunc
function, like:
select name, sum(count), date_trunc(\'minute\',timestamp) as timestamp
FROM table
WHERE xxx
GROUP BY name,date_trunc(\'minute\',timestamp)
ORDER BY timestamp
You can provide various resolutions like \'minute\',\'hour\',\'day\' etc... to date_trunc.
回答4:
i came across the same issue.
I found that it is easy to group by any minute interval is
just dividing epoch by minutes in amount of seconds and then either rounding or using floor to get ride of the remainder. So if you want to get interval in 5 minutes you would use 300 seconds.
SELECT COUNT(*) cnt,
to_timestamp(floor((extract(\'epoch\' from timestamp_column) / 300 )) * 300)
AT TIME ZONE \'UTC\' as interval_alias
FROM TABLE_NAME GROUP BY interval_alias
interval_alias cnt
------------------- ----
2010-11-16 10:30:00 2
2010-11-16 10:35:00 10
2010-11-16 10:45:00 8
2010-11-16 10:55:00 11
This will return the data correctly group by the selected minutes interval; however, it will not return the intervals that don\'t contains any data. In order to get those empty intervals we can use the function generate_series.
SELECT generate_series(MIN(date_trunc(\'hour\',timestamp_column)),
max(date_trunc(\'minute\',timestamp_column)),\'5m\') as interval_alias FROM
TABLE_NAME
Result:
interval_alias
-------------------
2010-11-16 10:30:00
2010-11-16 10:35:00
2010-11-16 10:40:00
2010-11-16 10:45:00
2010-11-16 10:50:00
2010-11-16 10:55:00
Now to get the result with interval with zero occurrences we just outer join both result sets.
SELECT series.minute as interval, coalesce(cnt.amnt,0) as count from
(
SELECT count(*) amnt,
to_timestamp(floor((extract(\'epoch\' from timestamp_column) / 300 )) * 300)
AT TIME ZONE \'UTC\' as interval_alias
from TABLE_NAME group by interval_alias
) cnt
RIGHT JOIN
(
SELECT generate_series(min(date_trunc(\'hour\',timestamp_column)),
max(date_trunc(\'minute\',timestamp_column)),\'5m\') as minute from TABLE_NAME
) series
on series.minute = cnt.interval_alias
The end result will include the series with all 5 minute intervals even those that have no values.
interval count
------------------- ----
2010-11-16 10:30:00 2
2010-11-16 10:35:00 10
2010-11-16 10:40:00 0
2010-11-16 10:45:00 8
2010-11-16 10:50:00 0
2010-11-16 10:55:00 11
The interval can be easily changed by adjusting the last parameter of generate_series. In our case we use \'5m\' but it could be any interval we want.
回答5:
The query will be something like:
SELECT
DATE_FORMAT(
MIN(timestamp),
\'%d/%m/%Y %H:%i:00\'
) AS tmstamp,
name,
COUNT(id) AS cnt
FROM
table
GROUP BY ROUND(UNIX_TIMESTAMP(timestamp) / 300), name
回答6:
You\'re probably going to have to break up your timestamp into ymd:HM and use DIV 5 to split the minutes up into 5-minute bins -- something like
select year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 5,
name,
count(b.name)
FROM time a, id b
WHERE a.user = b.user AND a.id = b.id AND b.name = \'John\'
AND a.timestamp BETWEEN \'2010-11-16 10:30:00\' AND \'2010-11-16 11:00:00\'
GROUP BY year(a.timestamp),
month(a.timestamp),
hour(a.timestamp),
minute(a.timestamp) DIV 12
...and then futz the output in client code to appear the way you like it. Or, you can build up the whole date string using the sql concat operatorinstead of getting separate columns, if you like.
select concat(year(a.timestamp), \"-\", month(a.timestamp), \"-\" ,day(a.timestamp),
\" \" , lpad(hour(a.timestamp),2,\'0\'), \":\",
lpad((minute(a.timestamp) DIV 5) * 5, 2, \'0\'))
...and then group on that
回答7:
How about this one:
select
from_unixtime(unix_timestamp(timestamp) - unix_timestamp(timestamp) mod 300) as ts,
sum(value)
from group_interval
group by ts
order by ts
;
回答8:
Not sure if you still need it.
SELECT FROM_UNIXTIME(FLOOR((UNIX_TIMESTAMP(timestamp))/300)*300) AS t,timestamp,count(1) as c from users GROUP BY t ORDER BY t;
2016-10-29 19:35:00 | 2016-10-29 19:35:50 | 4 |
2016-10-29 19:40:00 | 2016-10-29 19:40:37 | 5 |
2016-10-29 19:45:00 | 2016-10-29 19:45:09 | 6 |
2016-10-29 19:50:00 | 2016-10-29 19:51:14 | 4 |
2016-10-29 19:55:00 | 2016-10-29 19:56:17 | 1 |
回答9:
I found out that with MySQL probably the correct query is the following:
SELECT SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
\'%Y-%m-%d %H:%i:%S\' ) , 1, 19 ) AS ts_CEILING,
SUM(value)
FROM group_interval
GROUP BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
\'%Y-%m-%d %H:%i:%S\' ) , 1, 19 )
ORDER BY SUBSTRING( FROM_UNIXTIME( CEILING( timestamp /300 ) *300,
\'%Y-%m-%d %H:%i:%S\' ) , 1, 19 ) DESC
Let me know what you think.
回答10:
select
CONCAT(CAST(CREATEDATE AS DATE),\' \',datepart(hour,createdate),\':\',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2)) AS \'5MINDATE\'
,count(something)
from TABLE
group by CONCAT(CAST(CREATEDATE AS DATE),\' \',datepart(hour,createdate),\':\',ROUNd(CAST((CAST((CAST(DATEPART(MINUTE,CREATEDATE) AS DECIMAL (18,4)))/5 AS INT)) AS DECIMAL (18,4))/12*60,2))