SQL для впорядкування за номером - 1,2,3,4 тощо замість 1,10,11,12


86

Я намагаюся впорядкувати за числовим стовпцем у моїй базі даних, який має значення 1-999

Коли я використовую

ORDER_BY registration_no ASC

Я отримав….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

Таким чином, це, здається, впорядкування за першою цифрою, на відміну від числа.

Хтось знає, який SQL використовувати, якщо я хочу замовити це за значенням? Так 1,2,3,4,5,6і т.д.


11
Ваш стовпець має тип varchar, через який ви стикаєтесь із такою поведінкою.
Мехерзад

що таке тип даних стовпець registration_no?
Praveen Prasannan

9
Використовуйте order by registration_no + 0 ascдля вирішення своєї проблеми.
Мехерзад

10
Ніколи не слід зберігати числа в стовпці символів. Ваша проблема - прямий результат цієї помилки.
a_horse_with_no_name

Мій стовпець - Varchar, а дані, які я зберігаю, - Клас 10 / Клас 9 / Клас 8. Тепер клас 10 постає перед класом 8. Як це вирішити без необхідності робити стовпець display_order?
Vishnoo Rath

Відповіді:


139

Одним із способів упорядкування за додатними цілими числами, коли вони зберігаються як varchar, є упорядкування спочатку за довжиною, а потім за значенням:

order by len(registration_no), registration_no

Це особливо корисно, коли стовпець може містити нечислові значення.

Примітка: у деяких базах даних length()замість цього може бути викликана функція отримання довжини рядка len().


1
Це спрацює не у всіх випадках. У верхній частині голови випадки, які не спрацюють, - це суміші цілих чисел з; від’ємні числа, числа з провідними нулями, числа з дробами та слова та числа, об’єднані.
WonderWorker

10
@ Knickerless-Noggins. . . Прочитайте перше речення відповіді. Я думаю, це цілком зрозуміло.
Гордон Лінофф,

@GordonLinoff замовляє за одним стовпцем двічі не процесор і не потребує пам'яті?
loneStar

@Achyuth. . . Кількість клавіш в an order byмало впливає на продуктивність.
Гордон Лінофф

1
Для Oracle SQL використовуйте length()замістьlen()
Stevoisiak

61
ORDER_BY cast(registration_no as unsigned) ASC

явно перетворює значення в число. Ще однією можливістю досягти цього було б

ORDER_BY registration_no + 0 ASC

що змусить неявну розмову.

Насправді вам слід перевірити визначення таблиці та змінити його. Ви можете змінити тип даних на intтакий

ALTER TABLE your_table MODIFY COLUMN registration_no int;


3
ORDER_BY cast(registration_no as unsigned) ASC

дає бажаний результат із попередженнями.

Отже, краще піти

ORDER_BY registration_no + 0 ASC

для чистого результату без будь-яких попереджень SQL.


2

Я припускаю, що тип вашого стовпця STRING (CHAR, VARCHAR тощо), а процедура сортування сортує його як рядок. Що вам потрібно зробити, це перетворити значення в числове значення. Як це зробити, залежатиме від системи SQL, яку ви використовуєте.


1

Іноді у вас просто немає вибору щодо необхідності зберігати номери, змішані з текстом. В одному з наших додатків хост веб-сайту, який ми використовуємо для нашого сайту електронної комерції, робить фільтри динамічно поза списками. Немає можливості сортувати за будь-яким полем, крім відображеного тексту. Коли ми хотіли, щоб фільтри складалися зі списку, який містив такі речі, як 2 "до 8" 9 "до 12" 13 "до 15" тощо, нам потрібен був для сортування 2-9-13, а не 13-2-9, як це буде, коли читання числових значень. Тож я використав функцію реплікації SQL Server разом із довжиною найдовшого числа для заповнення будь-яких коротших чисел пробілом. Тепер 20 сортується після 3 тощо.

Я працював із поданням, яке дало мені мінімальну та максимальну довжину, ширину тощо для типу елемента та класу, і ось приклад того, як я робив текст. (LB n Low і LB n High - це нижній і високий кінці дужок 5 довжини.)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text

1

Я вважаю за краще робити "PAD" перед даними. MySql називає це LPAD, але ви можете попрацювати, щоб зробити те саме в SQL Server.

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

Ця формула надасть перші нулі на основі довжини стовпця 3. Ця функціональність дуже корисна в інших ситуаціях поза ПОРЯДКУВАННЯМ, тому я хотів надати цю опцію.

Результати: 1 стає 001, а 10 стає 010, тоді як 100 залишається незмінним.


0

Ця проблема полягає лише в тому, що ви оголосили стовпець у типі даних CHAR, VARCHAR або TEXT. Просто змініть тип даних на INT, BIGINT тощо. Це вирішить проблему Вашого замовлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.