group by range in mysql
Mysql as a delimiter for keywords uses backtick sign " ` ", not square brackets (like sql server)
Here's a solution that will work for any magnitude of diff:
select
concat(21 * round(diff / 21), '-', 21 * round(diff / 21) + 20) as `range`,
count(*) as `number of users`
from new_table
group by 1
order by diff;
Here's some testable code and its output:
create table new_table (user_number int, diff int);
insert into new_table values (2, 0), (1, 28), (2, 32), (1, 40), (1, 53), (1, 59), (1, 101), (1, 105), (2, 108), (2, 129), (2, 130), (1, 144);
-- run query, output is:
+---------+-----------------+
| range | number of users |
+---------+-----------------+
| 0-20 | 1 |
| 21-41 | 1 |
| 42-62 | 2 |
| 63-83 | 2 |
| 105-125 | 3 |
| 126-146 | 2 |
| 147-167 | 1 |
+---------+-----------------+
Here is general code to group by range since doing a case statement gets pretty cumbersome.
The function 'floor' can be used to find the bottom of the range (not 'round' as Bohemian used), and add the amount (19 in the example below) to find the top of the range. Remember to not overlap the bottom and top of the ranges!
mysql> create table new_table (user_number int, diff int);
Query OK, 0 rows affected (0.14 sec)
mysql> insert into new_table values (2, 0), (1, 28), (2, 32), (1, 40), (1, 53),
(1, 59), (1, 101), (1, 105), (2, 108), (2, 129), (2, 130), (1, 144);
Query OK, 12 rows affected (0.01 sec)
Records: 12 Duplicates: 0 Warnings: 0
mysql> select concat(21*floor(diff/21), '-', 21*floor(diff/21) + 20) as `range`,
count(*) as `number of users` from new_table group by 1 order by diff;
+---------+-----------------+
| range | number of users |
+---------+-----------------+
| 0-20 | 1 |
| 21-41 | 3 |
| 42-62 | 2 |
| 84-104 | 1 |
| 105-125 | 2 |
| 126-146 | 3 |
+---------+-----------------+
6 rows in set (0.01 sec)