T-Sql - Сортировать по буквенно-цифровой - PullRequest
2 голосов
/ 24 июля 2010

У меня есть список буквенно-цифровых токенов, скажем, '1a', '1b', '02', '03', '10', '11', и т. Д. *

Теперь, как лучше всего сделать заказ в этом списке токенов?

Я получаю '1a', '1b', '10', '11', '02', '03',

но мне нужно, чтобы оно было

'1a', '1b', '02', '03', '10', '11' 

UPDATE

хорошо, я делаю это после предложения, но оно не работает.

declare @tokens table(token varchar(20));

insert into @tokens
select '1a'
select '1b'
select '02'
select '10'

select * from @tokens
order by case
 when ISNUMERIC(token) = 1 then right('0000000000'+token+'0',10)
 else right('0000000000'+token,10)
 end

Я получаю ответ как '1b', '02', '10', '1a'

UPDATE2

Работает после внесения следующих изменений.

declare @tokens table(token varchar(20));

insert into @tokens
select '1a'
insert into @tokens
select '1b'
insert into @tokens
select '02'
insert into @tokens
select '10'


select token from @tokens
order by case
 when ISNUMERIC(token) = 1 then right('0000000000'+token+'0',10)
 else right('0000000000'+token,10)
 end

Спасибо всем вам за ваши прекрасные идеи.

Ответы [ 3 ]

8 голосов
/ 24 июля 2010

Самым простым решением является предварительное ожидание нулей

Select ...
From Table
Order By Right( '0000000000' + YourColumn, 10)

Однако это не будет учитывать альфа-символы.Чтобы иметь дело с альфа-символами, вам нужно знать, сколько потенциальных альфа-символов у вас может быть.Если он есть, вы можете сделать что-то вроде:

Select ...
From #Test
Order By Case
    When IsNumeric(NumVal) = 1 Then Right('0000000000' + NumVal + '0', 10)
    Else Right('0000000000' + NumVal, 10)
    End

ДОПОЛНЕНИЕ

Тестовый прогон:

If object_id('tempdb..#Test') is not null
    Drop Table #Test

Create Table #Test ( NumVal varchar(10) )
Insert #Test(NumVal) Values('02')
Insert #Test(NumVal) Values('03')
Insert #Test(NumVal) Values('1a')
Insert #Test(NumVal) Values('1b')
Insert #Test(NumVal) Values('10')
Insert #Test(NumVal) Values('11')

Select NumVal
From #Test
Order By Case
    When IsNumeric(NumVal) = 1 Then Right('0000000000' + NumVal + '0', 10)
    Else Right('0000000000' + NumVal, 10)
    End

Results:
1a
1b
02
03
10
11

Примечание о моем решении,Если это тот случай, когда буквенный символ (ы) имеет особое значение, то, как предложил Эрик Робертсон, вы должны разбить данные на отдельные столбцы.Вышеупомянутое решение будет обрабатывать только два очень специфических случая: все числовое значение, значение с одним завершающим буквенным символом.Если данные могут содержать несколько буквенных символов или буквенный символ иногда располагается не в конце значения, мое решение не будет работать.Кроме того, следует отметить, что мое решение приведет к тому, что при сканировании таблицы будет оцениваться упорядоченная строка для каждого значения.

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

2 голосов
/ 24 июля 2010

Если вы знакомы с C # или VB.net, возможно, стоит подумать о написании функции CLR, которая выполняет сортировку за вас, так как этот порядок сортировки достаточно нестандартный, чтобы его было сложно и всесторонне описать в TSQL..

1 голос
/ 24 июля 2010

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

Функции преобразования из альфы в int медленны и не могут использовать индексирование для ускорения запросов. По мере роста вашего набора данных решение такого типа будет только медленнее и перегружать вашу базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...