SQL за подреждане по номер - 1,2,3,4 и т.н. вместо 1,10,11,12

Опитвам се да подредя по числова колона в моята база данни, която има стойности 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 и т.н


person Konnor262    schedule 13.05.2013    source източник
comment
Вашата колона е от тип varchar, поради което се сблъсквате с това поведение.   -  person Meherzad    schedule 13.05.2013
comment
какъв е типът данни на колоната registration_no?   -  person Praveen Prasannan    schedule 13.05.2013
comment
Използвайте order by registration_no + 0 asc, за да решите проблема си.   -  person Meherzad    schedule 13.05.2013
comment
Не трябва никога да съхранявате числа в колона със знаци. Вашият проблем е пряк резултат от тази грешка.   -  person a_horse_with_no_name    schedule 13.05.2013
comment
Моята колона е Varchar и данните, които съхранявам, са клас 10/клас 9/клас 8. Сега клас 10 идва преди клас 8. Как да разреша това, без да се налага да правя колона за display_order?   -  person Vishnoo Rath    schedule 29.08.2020
comment
За да отговоря на собствения си въпрос. Един блог предложи сортиране по len(title), заглавие, за да се постигне сортиране по естествен ред. mysqltutorial.org/mysql-natural-sorting   -  person Vishnoo Rath    schedule 29.08.2020


Отговори (8)


Един от начините за подреждане по положителни цели числа, когато те се съхраняват като varchar, е първо да се подреди по дължината и след това по стойността:

order by len(registration_no), registration_no

Това е особено полезно, когато колоната може да съдържа нечислови стойности.

Забележка: в някои бази данни функцията за получаване на дължината на низ може да се нарича length() вместо len().

person Gordon Linoff    schedule 13.05.2013
comment
Това няма да работи във всички случаи. Извън горната част на главата, случаите, които няма да работят, са смеси от цели числа с; отрицателни числа, числа с водещи нули, числа с дроби и комбинирани думи и числа. - person WonderWorker; 14.06.2017
comment
@Knickerless-Noggins . . . Прочетете първото изречение от отговора. Мисля, че е съвсем ясно. - person Gordon Linoff; 14.06.2017
comment
@GordonLinoff подрежда по една и съща колона два пъти не е интензивно процесор и памет? - person loneStar; 05.11.2017
comment
@Achyuth . . . Броят на ключовете в order by има малък ефект върху производителността. - person Gordon Linoff; 05.11.2017
comment
Спаси живота ми днес. В моя случай беше length(). - person Paco; 29.03.2019
comment
Можете ли да обясните ефективността на това решение срещу просто преобразуване на низа в цяло число, както е предложено в други отговори? - person Luis; 05.05.2019
comment
@Луис. . . Изпълнението ще бъде почти същото, защото режийните разходи са подобни. Преобразуването на типове и извикванията на функции са склонни да изключват използването на индекси. Избягването на типови преобразувания елиминира един източник на грешки по време на изпълнение. - person Gordon Linoff; 05.05.2019
comment
За Oracle SQL използвайте length() вместо len() - person Stevoisiak; 04.03.2020
comment
Как да приложим същото на CodeIgniter? @GordonLinoff - person yeshansachithak; 17.05.2020
comment
Точно от каквото имах нужда. - person Henry Ing-Simmons; 10.02.2021

ORDER_BY cast(registration_no as unsigned) ASC

изрично преобразува стойността в число. Друга възможност за постигане на същото би била

ORDER_BY registration_no + 0 ASC

което ще наложи имплицитен разговор.

Всъщност трябва да проверите дефиницията на таблицата и да я промените. Можете да промените типа данни на int по този начин

ALTER TABLE your_table MODIFY COLUMN registration_no int;
person juergen d    schedule 13.05.2013

Ако използвате SQL Server:

ORDER_BY cast(registration_no as int) ASC
person IPOSTEDONCE    schedule 03.04.2015

ORDER_BY cast(registration_no as unsigned) ASC

дава желания резултат с предупреждения.

Следователно, по-добре да отидете

ORDER_BY registration_no + 0 ASC

за чист резултат без никакви SQL предупреждения.

person priyanka    schedule 04.03.2019
comment
Можете ли да обясните защо извършването на + 0 работи? Тествах го на моя набор от данни и наистина работи, но ми е любопитно защо? Преобразува ли го в число преди поръчка? - person Joshua Pinter; 12.12.2020

Предполагам, че вашият тип колона е STRING (CHAR, VARCHAR и т.н.) и процедурата за сортиране я сортира като низ. Това, което трябва да направите, е да конвертирате стойността в числова стойност. Как да го направите ще зависи от SQL системата, която използвате.

person Community    schedule 13.05.2013

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

Работех с изглед, който ми даде минималните и максималните дължини, ширини и т.н. за типа и класа на елемента и ето пример за това как направих текста. (LBnLow и LBnHigh са ниският и високият край на 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
person Joey Morgan    schedule 23.08.2017

Предпочитам да правя "PAD" пред данните. MySql го нарича LPAD, но можете да работите по пътя си, за да направите същото нещо в SQL Server.

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

Тази формула ще предостави водещи нули въз основа на дължината на колоната от 3. Тази функционалност е много полезна в други ситуации извън ORDER BY, затова исках да предоставя тази опция.

Резултати: 1 става 001, а 10 става 010, докато 100 остава същото.

person SQLCodingIsFunnn    schedule 19.08.2016

Този проблем е само защото сте декларирали колоната в тип данни CHAR, VARCHAR или TEXT. Просто променете типа данни на INT, BIGINT и т.н. Това ще реши проблема с вашето персонализирано подреждане.

person Dev Rathi    schedule 27.11.2019