MySQL: ORDER BY создает неправильный порядок, используя длинную строку - PullRequest
0 голосов
/ 26 апреля 2018

У меня есть таблица со столбцом VARCHAR(255), которая содержит следующие строки.

1
2
5
22
text

Мне нужно нормализовать строки и отсортировать их вот так. Я добавляю к ним префикс 0, чтобы при оформлении заказа я получал следующую информацию:

0001
0002
0005
0022
text

Вот запрос:

SELECT right(concat('000000000000000000000000000000000000', test), 36)
FROM my_table
ORDER BY right(concat('000000000000000000000000000000000000', test), 36);

Если number_of_chars в right() вызов достаточно мал (скажем, 16), порядок правильный, но если я использую 36, порядок неправильный: строка 5 предшествует 2.

000000000000000000000000000000000005
000000000000000000000000000000000002

Вопрос: В чем причина такого поведения? Это ошибка? Как это исправить?

Вот как выглядит мой стол:

mysql> describe my_table;
+----------------------------+--------------+------+-----+---------+-------+
| Field                      | Type         | Null | Key | Default | Extra |
+----------------------------+--------------+------+-----+---------+-------+
| id                         | varchar(255) | NO   | PRI | NULL    |       |
| test                       | varchar(255) | NO   | UNI | NULL    |       |
+----------------------------+--------------+------+-----+---------+-------+

Я использую MySQL 5.7.15

Ответы [ 3 ]

0 голосов
/ 26 апреля 2018

Это очень воспроизводимо и довольно любопытно. Например, это приводит к неправильному порядку:

SELECT right(concat(repeat('0', 36), test), 36) as val
FROM (select 'abcd' as test union all
      select '5' as test union all
      select '2' as test union all
      select '13' as test union all
      select '10013' as test union all
      select 'def' as test
     ) t
ORDER BY val ;

Интересно, что добавление DESC, похоже, решает проблему, но ASC - нет.

Как правило, в этом случае вы хотите, чтобы сначала были цифры, а затем весь текст. Ваша версия будет чередовать не числа с номерами одинаковой длины.

Я рекомендую делать это с отдельными выражениями:

ORDER BY (left(test, 1) between '0' and '9') desc,
         test + 0,
         test

Эта сортировка действительно работает.

0 голосов
/ 26 апреля 2018

Вы используете строки по порядку, поэтому он не будет считать числа n строк по-другому. Например У вас 11,12,01,03, Вы получите

01 11 12 03 только так

0 голосов
/ 26 апреля 2018

Кажется, что после 21 символа правильная подстрока с заполнением строк не работает .. но Вы можете просто использовать Ipad эту работу также для 100 или более

SELECT test
FROM my_table
ORDER BY lpad(test,100, '0')
...