Reputation: 45062
I have a set or records and I want to count and group them by a certain range e.g. I want to count the records that were created by groups of X days
e.g. SELECT COUNT(*) FROM `table` GROUP BY /*`created` 3 days/*
Upvotes: 6
Views: 5683
Reputation: 171
Thanks @Ronnis, I use your example and finally solve my problem.
And there is a small mistake I found, in example, I add one row
insert into t1(created) values (date '2011-01-21')
Now I get:
+----------+--------------+--------------+----------+
| days_ago | min(created) | max(created) | count(*) |
+----------+--------------+--------------+----------+
| 1986 | 2011-01-20 | 2011-01-21 | 2 |
| 1989 | 2011-01-17 | 2011-01-19 | 3 |
| 1992 | 2011-01-14 | 2011-01-16 | 3 |
| 1995 | 2011-01-11 | 2011-01-13 | 3 |
| 1998 | 2011-01-09 | 2011-01-10 | 2 |
+----------+--------------+--------------+----------+
As you can see that days divide into 2, 3, 3, 3, 2 which not what I expected.
I change SQL as
select floor(datediff(created, '2011-01-09') / 3) * 3 as days_before
,min(created)
,max(created)
,count(*)
from t1
group by floor(datediff(created, '2011-01-09') / 3);
Just get datediff from created to start date, and now I get:
+-------------+--------------+--------------+----------+
| days_before | min(created) | max(created) | count(*) |
+-------------+--------------+--------------+----------+
| 0 | 2011-01-09 | 2011-01-11 | 3 |
| 3 | 2011-01-12 | 2011-01-14 | 3 |
| 6 | 2011-01-15 | 2011-01-17 | 3 |
| 9 | 2011-01-18 | 2011-01-20 | 3 |
| 12 | 2011-01-21 | 2011-01-21 | 1 |
+-------------+--------------+--------------+----------+
That might be more suitable.
Upvotes: 2
Reputation: 12843
Here is an example with dates.
create table t1(created date not null);
insert
into t1(created) values (date '2011-01-09')
,(date '2011-01-10')
,(date '2011-01-11')
,(date '2011-01-12')
,(date '2011-01-13')
,(date '2011-01-14')
,(date '2011-01-15')
,(date '2011-01-16')
,(date '2011-01-17')
,(date '2011-01-18')
,(date '2011-01-19')
,(date '2011-01-20');
select floor(datediff(now(), created) / 3) * 3 as days_ago
,min(created)
,max(created)
,count(*)
from t1
group
by floor(datediff(now(), created) / 3);
+----------+--------------+--------------+----------+
| days_ago | min(created) | max(created) | count(*) |
+----------+--------------+--------------+----------+
| 0 | 2011-01-18 | 2011-01-20 | 3 |
| 3 | 2011-01-15 | 2011-01-17 | 3 |
| 6 | 2011-01-12 | 2011-01-14 | 3 |
| 9 | 2011-01-09 | 2011-01-11 | 3 |
+----------+--------------+--------------+----------+
4 rows in set (0.00 sec)
Upvotes: 8
Reputation: 17608
You can do something like
SELECT COUNT(*) FROM table GROUP BY FLOOR(created / 3)
... I think.
Although if created
is a date field, you'll have to do a little more jiggering to get it into a number value for this to work.
Upvotes: 4