С проблемой СВЕРТКИ в порядке диапазона

#mysql

#mysql

Вопрос:

После добавления свертки WITH в оператор GROUP BY диапазоны были переупорядочены. Как это можно исправить?

Вот код

                  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.
 

Комментарии:

1. Почему тег mysqli? Здесь нет кода приложения.

2. @Strawberry -извините за мою ошибку.

3. Если вы добавите ‘ 0’ к ORDER BY, я подозреваю, что это исправит ситуацию, но у меня возникнет соблазн сделать что-то подобное в коде приложения.

4. @Strawberry — это сработало. Однако он скопировал последний диапазон 2001-2500, когда он должен быть нулевым. Есть ли способ удалить дублированный диапазон?

5. @toff какая у вас версия MySQL?

Ответ №1:

Столбец Revenue представляет собой строку, поэтому результаты сортируются в алфавитном порядке.
Чтобы отсортировать столбец как число, решением было бы привести Revenue к такому числу, как:

 ORDER BY Revenue IS NULL, Revenue   0
 

но, как я тестировал в MySQL 8.0.22 здесь (с предыдущей скрипкой ваших данных), по какой-то причине это не работает (может быть, ошибка?).
В любом случае вы тоже должны попробовать.

Код, который сработал, таков:

 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
 

Смотрите демонстрацию.
Результаты:

 > 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
 

Комментарии:

1. @forpas-Если бы мог быть способ заменить NULL на TOTAL, было бы лучше.

2. Самый простой способ сделать это с помощью COALESCE() . Проверьте это: dbfiddle.uk /…