Сортировка поля varchar численно в MySQL
У меня есть поле number
типа varchar
. Несмотря на то, что он имеет тип varchar
, он сохраняет целочисленные значения с необязательными ведущими нулями. Сорт заказывает их лексикографически ("42"
предшествует "9"
). Как я могу упорядочить по числовым значениям ("9"
до "42"
)?
В настоящее время я использую запрос:
SELECT * FROM table ORDER BY number ASC
Ответы
Ответ 1
Есть несколько способов сделать это:
- Храните их как числовые значения, а не строки. Вы уже уклонились от этого, так как хотите сохранить строки, такие как
00100
неповрежденными с ведущими нулями.
- Сортировать по строкам в виде числа. Это будет работать, но имейте в виду, что это убийца производительности для приличных баз данных. Функции на строки не очень хорошо масштабируются.
- Добавьте третий столбец, который является числовым эквивалентом строки и индекса. Затем используйте триггер insert/update, чтобы убедиться, что он установлен правильно, когда изменяется столбец строки.
Поскольку подавляющее большинство баз данных читается гораздо чаще, чем написано, этот третий вариант выше амортизирует стоимость расчета (сделанного при вставке/обновлении) по всем выбранным. Ваши выборки будут ослеплятельно быстрыми, так как они используют числовой столбец для упорядочения (и не для каждой строки).
Ваши вставки и обновления будут медленнее, но цена, которую вы платите, и, честно говоря, стоит заплатить.
Использование триггера поддерживает свойства ACID таблицы, поскольку эти два столбца находятся в шаге. И это известная идиома, которую вы обычно можете откусить в течение времени в большинстве оптимизаций производительности.
Мы использовали этот "трюк" во многих ситуациях, например, сохраняя версии с фамилией с нижней строкой вместе с оригиналами (вместо того, чтобы использовать что-то вроде tolower
), длины идентификационных строк, чтобы найти всех пользователей с 7-символьным (вместо использования len
) и т.д.
Имейте в виду, что вы можете вернуться из третьей нормальной формы для производительности, если вы понимаете (и смягчаете) последствия.
Ответ 2
Попробуйте это
SELECT * FROM table_name ORDER BY CAST(field_name as SIGNED INTEGER) ASC
Ответ 3
На самом деле я нашел что-то интересное:
SELECT * FROM mytable ORDER BY LPAD(lower(mycol), 10,0) DESC
Это позволяет вам заказать поле, например:
1
2
3
10
A
A1
B2
10A
111
Ответ 4
SELECT * FROM table ORDER BY number + 0
Ответ 5
Трюк, который я только что узнал. Добавьте '+0' в предложение порядка поля varchar:
SELECT * FROM table ORDER BY number+0 ASC
Теперь я вижу этот ответ выше. Мне интересно, является ли это типом поля и целого числа. Я не сравнивал производительность. Отлично работает.
Ответ 6
Для таблицы со значениями, такими как Er353, ER 280, ER 30, ER36
сортировка по умолчанию даст
ER280
ER30
ER353
ER36
select fieldname,substring(fieldname, 1, 2) as bcd, CONVERT(SUBSTRING(fieldname, 3, 9),UNSIGNED INTEGER) AS num from table_name order by bcd,num;
результаты будут в этом порядке
ER30
ER36
ER280
ER353
Ответ 7
вы можете получить заказ в соответствии с вашим требованием, используя следующий SQL-запрос
SELECT * FROM mytable ORDER BY ABS(mycol)
Ответ 8
для столбца username
, содержащего VARCHAR
следующим образом:
username1
username10
username100
можно было сделать:
SELECT username,
CONVERT(REPLACE(username, 'username', ''), UNSIGNED INTEGER) AS N
FROM users u
WHERE username LIKE 'username%'
ORDER BY N;
это не дешево, но делает работу.
Ответ 9
SELECT * FROM table ORDER BY number ASC
Должен отображать то, что вы хотите отобразить.. похоже, что вы сортируете его с помощью id
или number
в данный момент не определяется как integer
.
Ответ 10
Грубый и готовый: порядок по 1 * field_name