Why this query giving wrong output?
You don't need the long CASE, use MySQL's CEILING function - https://dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html#function_ceiling
What is the data type for the rating column? My guess is that it's a FLOAT, and being an approximate, your actual values fall within the ranges that aren't covered by the CASE , 2.00001 for example. Change it to DECIMAL to avoid similar issues.
When using CASE, it's a good idea to always include an ELSE clause. Try adding ELSE -1  or other value just to troubleshoot this issue, and you will see for yourself.

HTH
UPDATE - I stand partly corrected. While my answer and points are still valid, I believe that @RickJames and @RolaondoMySQLDBA were right for this case as well.
According to IEEE 754 these number do happen to have exact representation as FLOAT, and the problem was your CASE. Using CEILING is better than CASE and IF for this, but to understand the root issue see @RolandoMySQLDBA Answer below, and @RickJames comments.
UPDATE 2019-07-21 18:03 EDT (RolandoMySQLDBA)
In all fairness, CEILING() does make the most sense.
I ran this
SELECT CEILING(rating) ratings,COUNT(1)
FROM user_review GROUP BY CEILING(rating);

on the sample data and got this
mysql&gt; SELECT CEILING(rating) ratings,COUNT(1)
    -&gt; FROM user_review GROUP BY CEILING(rating);
+---------+----------+
| ratings | COUNT(1) |
+---------+----------+
|       5 |        3 |
|       3 |        2 |
|       4 |        2 |
|       1 |        2 |
|       2 |        2 |
+---------+----------+
5 rows in set (0.00 sec)

So, CEILING() is the most concise in this case. +1 to you !!!