Перетворити текст у число у запиті 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. Якщо ім’я не містить жодних чисел, це зберегти для використання цього рішення?


1
ім'я - це саме ім'я, або це може бути будь-який символ? Я маю на увазі: це строка чотири символи завдовжки чи це справжнє ім’я?
Марко

nameможе бути будь-яка послідовність букв.
czuk

1
можливий дублікат природного сортування mysql
Shakti Singh

Відповіді:


256

Це має працювати:

SELECT field,CONVERT(SUBSTRING_INDEX(field,'-',-1),UNSIGNED INTEGER) AS num
FROM table
ORDER BY num;

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);


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;

1
Ви впевнені, що ЗАМОВЛЕННЯ використовує число як число без використання CONVERT? Я не впевнений, але це може бути .. Я просто запитую себе :)
Марко

4

один простий спосіб SELECT '123' + 0


Хоча цей код може допомогти вирішити проблему, надаючи додатковий контекст щодо того, чому та / або як він відповідає на це питання, значно покращить його довгострокове значення. Будь ласка , змініть свій відповідь , щоб додати деякі пояснення.
Toby Speight

Це не дало відповіді на запитання, але це була відповідь, яку я шукав.
Сагар Шах

ваше рішення є найелегантнішим і практичним - на жаль, ви його не надали в контексті запитання з конкретним виразом для даного прикладу - будь ласка, змініть його на конкретне.
чукко


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


-5

Загальний спосіб зробити:

SELECT * FROM your_table ORDER BY LENTH(your_column) ASC, your_column ASC
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.