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, из-за которого вы столкнулись с таким поведением.
Meherzad

каков тип данных столбца registration_no?
Правин Прасаннан

9
Используйте order by registration_no + 0 ascдля решения вашей проблемы.
Meherzad

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

Мой столбец - Varchar, а данные, которые я храню, - это Class 10 / Class 9 / Class 8. Теперь класс 10 предшествует классу 8. Как мне решить эту проблему, не прибегая к столбцу display_order?
Вишну Ратх

Ответы:


139

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

order by len(registration_no), registration_no

Это особенно полезно, когда столбец может содержать нечисловые значения.

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


1
Это не сработает во всех случаях. Вне всяких сомнений, случаи, которые не будут работать, представляют собой смесь целых чисел с; отрицательные числа, числа с ведущими нулями, числа с дробями, а также слова и числа вместе.
WonderWorker

10
@ Knickerless-Noggins. . . Прочтите первое предложение ответа. Я думаю, это вполне понятно.
Гордон Линофф

@GordonLinoff дважды заказывает один и тот же столбец, это не требует интенсивного использования процессора и памяти?
loneStar 05

@Achyuth. . . Количество клавиш в order byэлементе мало влияет на производительность.
Гордон Линофф 05

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 Replicate вместе с длиной самого длинного числа, чтобы дополнить любые более короткие числа начальным пробелом. Теперь 20 сортируется после 3 и так далее.

Я работал с представлением, которое давало мне минимальную и максимальную длину, ширину и т. Д. Для типа и класса элемента, и вот пример того, как я делал текст. (LB n Low и LB n High - это нижняя и верхняя границы пяти скобок длины.)

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

Я предпочитаю делать "ПАД" данным. MySql называет это LPAD, но вы можете сделать то же самое в SQL Server.

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

Эта формула предоставит ведущие нули на основе длины столбца 3. Эта функция очень полезна в других ситуациях, кроме ORDER BY, поэтому я хотел предоставить эту опцию.

Результаты: 1 становится 001, 10 становится 010, а 100 остается прежним.


0

Эта проблема возникает только потому, что вы объявили столбец с типом данных CHAR, VARCHAR или TEXT. Просто измените тип данных на INT, BIGINT и т. Д. Это решит проблему вашего индивидуального порядка.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.