Конвертировать текст в число в запросе MySQL

138

Можно ли конвертировать текст в число в запросе MySQL? У меня есть столбец с идентификатором, который состоит из имени и числа в формате «имя-номер». Столбец имеет тип VARCHAR. Я хочу отсортировать строки по номеру (строки с одинаковым именем), но столбец отсортирован в соответствии с порядком символов, т.е.

name-1
name-11
name-12
name-2

Если я урежу число, могу ли я преобразовать число 'varchar' в 'реальное' число и использовать его для сортировки строк? Я хотел бы получить следующий заказ.

name-1
name-2
name-11
name-12

Я не могу представить число в виде отдельного столбца.

отредактировано 2011-05-11 9:32

Я нашел следующее решение ... ORDER BY column * 1. Если имя не будет содержать цифр, будет ли сохранено использование этого решения?

czuk
источник
1
имя это точно имя или это может быть любой персонаж? Я имею в виду: это строка длиной в четыре символа или настоящее имя?
Марко
nameможет быть любая последовательность букв.
czuk
1
возможный дубликат естественной сортировки mysql
Шакти Сингх

Ответы:

256

Это должно работать:

SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;
Marco
источник
1
Не могли бы вы добавить объяснение и ссылку на документацию?
Анджело Фукс
Моя строка похожа на "name-abc12". Добавляя ваш код, он работает только в том случае, если начальные символы после «-» не начинаются с буквы. @Marco Можете ли вы сказать мне способ игнорировать буквы без условия где?
Эдуардо
1
@ Eduardo Мой запрос должен получить строку после «-» и преобразовать ее в число (оно ДОЛЖНО быть числом). В вашем случае я бы использовал регулярное выражение, вероятно ...
Марко
Регулярное выражение @Marco сделало это, спасибо за совет.
Эдуардо
32

Вы можете использовать SUBSTRINGи CONVERT:

SELECT stuff
FROM table
WHERE conditions
ORDER BY CONVERT(SUBSTRING(name_column, 6), SIGNED INTEGER);

Где name_columnнаходится столбец со значениями «name-». Команда SUBSTRINGудаляет все до шестого символа (то есть префикса «name-»), а затем CONVERTпреобразует оставшееся в настоящее целое число.

ОБНОВЛЕНИЕ : Учитывая изменяющиеся обстоятельства в комментариях (то есть префикс может быть любым), вам придется добавить LOCATEв смесь:

ORDER BY CONVERT(SUBSTRING(name_column, LOCATE('-', name_column) + 1), SIGNED INTEGER);

Это, конечно, предполагает, что в нечисловом префиксе нет дефисов, но соответствующий комментарий говорит, что:

name может быть любая последовательность букв

так что это должно быть безопасным предположением.

мю слишком коротка
источник
Отвечая на мой комментарий, он сказал нам, что имя может быть любой последовательностью символов, поэтому я не уверен, что вы можете использовать SUBSTRING(name_column, 6). Я знаю, вы опубликовали это, когда он не сказал нам этого ...
Марко
@Marco: Спасибо за внимание, я добавил обновление, которое должно позаботиться о новой информации о префиксах. Но да, ваш SUBSTRING_INDEX приятнее.
мю слишком коротка
23

Просто используйте CAST,

CAST(column_name AS UNSIGNED)

Тип результата приведения может быть одним из следующих значений:

BINARY[(N)]
CHAR[(N)]
DATE
DATETIME
DECIMAL[(M[,D])]
SIGNED [INTEGER]
TIME
UNSIGNED [INTEGER]
Сибин Джон Маттаппаллил
источник
14

Вы можете использовать CAST () для преобразования из строки в int. напримерSELECT CAST('123' AS INTEGER);

verdesmarald
источник
15
Это конкретная версия? Мне нужно использовать SELECT CAST('123' AS SIGNED INTEGER);или SELECT CAST('123' AS UNSIGNED INTEGER);заставить его работать.
Hobo
10
SELECT *, CAST(SUBSTRING_INDEX(field, '-', -1) AS UNSIGNED) as num FROM tableName ORDER BY num;
Gaurav
источник
1
Вы уверены, что ORDER BY использует num как число без использования CONVERT? Я не уверен, но это может быть .. Я просто спрашиваю себя :)
Марко
4

один простой способ ВЫБРАТЬ «123» + 0

ВРК РАО
источник
Хотя этот код может помочь решить проблему, предоставление дополнительного контекста относительно того, почему и / или как он отвечает на вопрос, значительно улучшит его долгосрочную ценность. Пожалуйста, отредактируйте свой ответ, чтобы добавить пояснения.
Тоби Спейт
Это не ответило на вопрос, но это был ответ, который я искал.
Сагар Шах
Ваше решение является наиболее элегантным и практичным - к сожалению, вы не предоставили его в контексте вопроса с конкретным выражением для данного примера - пожалуйста, измените его, чтобы оно было конкретным.
Chukko
2

если ваш первичный ключ представляет собой строку в формате, подобном

ABC / EFG / EE / 13/123 (порядковый номер),
этот тип строки можно легко использовать для сортировки с разделителем ("/")

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

SELECT * FROM `TABLE_NAME` ORDER BY 
CONVERT(REVERSE(SUBSTRING(REVERSE(`key_column_name`), 1, LOCATE('/', REVERSE(`key_column_name`)) - 1)) , UNSIGNED INTEGER) DESC
Harsha
источник
0
cast(REGEXP_REPLACE(NameNumber, '[^0-9]', '') as UNSIGNED)
Джайрам Кумар
источник
-5

Общий способ сделать:

SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
Azzu
источник