Сортировка поля varchar численно в MySQL - PullRequest
37 голосов
/ 14 января 2011

У меня есть поле number типа varchar. Хотя он имеет тип varchar, он хранит целочисленные значения с необязательными начальными нулями. Сортировка упорядочивает их лексикографически ("42" предшествует "9"). Как заказать по числовым значениям ("9" до "42")?

В настоящее время я использую запрос:

SELECT * FROM table ORDER BY number ASC

Ответы [ 10 ]

67 голосов
/ 14 января 2011

Попробуйте это

SELECT * FROM table_name ORDER BY CAST(field_name as SIGNED INTEGER) ASC
37 голосов
/ 14 января 2011

Есть несколько способов сделать это:

  1. Сохраните их как числовые значения, а не как строки.Вы уже обесценили это, поскольку хотите сохранить строки типа 00100 без изменений с ведущими нулями.
  2. Упорядочение по строкам, приведенным как числовые.Это будет работать, но имейте в виду, что это убийца производительности для баз данных приличного размера.Функции для каждой строки не очень хорошо масштабируются.
  3. Добавьте третий столбец, который является числовым эквивалентом строки и индекса для этого.Затем используйте триггер insert / update, чтобы убедиться, что он установлен правильно при изменении строкового столбца.

Поскольку подавляющее большинство баз данных читается гораздо чаще, чем записывается, этот третий вариант выше амортизируетстоимость расчета (сделанная на insert / update) для всех вариантов.Ваши выборы будут ослепительно быстрыми, так как они используют числовой столбец для заказа (а не функции для каждой строки).

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

Использование триггера поддерживает свойства таблицы ACID, поскольку два столбца находятся в шаге.И это общеизвестная идиома: обычно при оптимизации производительности вы можете обменять пространство на время.

Мы использовали этот «трюк» во многих ситуациях, таких как хранение версий фамилий в нижнем регистре вместе соригиналы (вместо использования чего-то вроде tolower), длины идентифицирующих строк для поиска всех пользователей с 7-символьными (вместо использования len) и т. д.

Имейте в виду, что это нормальновернуться к третьей нормальной форме для выполнения, если вы понимаете (и смягчаете) последствия.

28 голосов
/ 11 сентября 2013

На самом деле я нашел что-то интересное:

SELECT * FROM mytable ORDER BY LPAD(LOWER(mycol), 10,0) DESC

Это позволяет вам упорядочить поле следующим образом:

1
2
3
10
A
A1
B2
10A
111
19 голосов
/ 28 января 2011
SELECT * FROM table ORDER BY number + 0
16 голосов
/ 12 декабря 2012

Трюк, который я только что узнал. Добавьте '+0' к предложению порядка полей varchar:

SELECT * FROM table ORDER BY number+0 ASC

Теперь я вижу этот ответ выше. Мне интересно, если это типизирование поля и целое число. Я не сравнивал производительность. Работает отлично.

5 голосов
/ 23 ноября 2012

Для таблицы со значениями, такими как 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

1 голос
/ 14 апреля 2016

заданный столбец 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;

это не дешево, но делает работу.

1 голос
/ 05 июня 2012

вы можете получить заказ в соответствии с вашими требованиями, используя следующий запрос sql

SELECT * FROM mytable ORDER BY ABS(mycol)
0 голосов
/ 07 августа 2015

Грубый и готовый: заказ по 1 * field_name

0 голосов
/ 14 января 2011
SELECT * FROM table ORDER BY number ASC

Должно отображаться то, что вы хотите, чтобы оно отображалось .. похоже, вы сортируете его по id или number не определено как integer на данный момент.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...