'WITH ROLLUP issue on range order

After adding the WITH ROLLUP in the GROUP BY statement the ranges reordered. How can this be fixed?

Here is the code

                 SUM(product.product_id = 1) AS Soda,
                 SUM(product.product_id = 2) AS Liquor,
                 SUM(product.product_id = 3) AS Lemon,
                 SUM(product.product_id = 4) AS Mango,
                 SUM(product.product_id = 5) AS Inhaler,
                 SUM(1) AS Count
FROM line_item
JOIN product USING (product_id)
JOIN ( SELECT    0 lowest,  500 highest UNION
       SELECT  501   , 1000             UNION
       SELECT 1001   , 1500             UNION
       SELECT 1501   , 2000             UNION
       SELECT 2001   , 2500 ) ranges ON product.price * line_item.quantity BETWEEN ranges.lowest AND ranges.highest
GROUP BY Revenue WITH ROLLUP;

Result:
+-------------+------+--------+-------+-------+---------+-------+
| Revenue     | Soda | Liquor | Lemon | Mango | Inhaler | Count |
+-------------+------+--------+-------+-------+---------+-------+
| 0 - 500     |    4 |      0 |     4 |     0 |       1 |     9 |
| 1001 - 1500 |    0 |      1 |     0 |     2 |       2 |     5 |
| 1501 - 2000 |    0 |      2 |     0 |     0 |       1 |     3 |
| 2001 - 2500 |    0 |      1 |     0 |     0 |       0 |     1 |
| 501 - 1000  |    0 |      0 |     0 |     2 |       0 |     2 |
| NULL        |    4 |      4 |     4 |     4 |       4 |    20 |
+-------------+------+--------+-------+-------+---------+-------+

The range 501 - 1000 moved to the bottom, it should be next to the 0-500 range.


Solution 1:[1]

The column Revenue is a string so the results are sorted alphabetically.
In order to sort the column as a number, a solution would be to cast Revenue to a number like:

ORDER BY Revenue IS NULL, Revenue + 0

but as I tested in MySql 8.0.22 here (with a previous fiddle of your data), for some reason, it does not work (maybe a bug?).
In any case you should try it too.

The code that worked is this:

GROUP BY ranges.lowest, ranges.highest WITH ROLLUP
HAVING GROUPING(ranges.lowest) = 1 OR GROUPING(ranges.highest) = 0
ORDER BY GROUPING(ranges.lowest), ranges.lowest

See the demo.
Results:

> Revenue   | Soda | Liquor | Lemon | Mango | Inhaler | Count
> :-------- | ---: | -----: | ----: | ----: | ------: | ----:
> 0-500     |    4 |      0 |     4 |     0 |       1 |     9
> 501-1000  |    0 |      0 |     0 |     2 |       0 |     2
> 1001-1500 |    0 |      1 |     0 |     2 |       2 |     5
> 1501-2000 |    0 |      2 |     0 |     0 |       1 |     3
> 2001-2500 |    0 |      1 |     0 |     0 |       0 |     1
> null      |    4 |      4 |     4 |     4 |       4 |    20

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 forpas