2010-07-24 4 views
2

У меня есть список буквенно-цифровых маркеров, скажем, '1a', '1b', '02', '03', '10', '11', и т.д ...T-Sql - Заказывайте на Alphanumeric

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

Я получаю '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 

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

+0

Какую базу вы используете? – Oded

+0

@Oded - sql server 2008, исправил заголовок, спасибо. – SoftwareGeek

+0

@SoftwareGeek - Из любопытства, что представляют данные? Значит ли алфавитный символ особый смысл? – Thomas

ответ

8

Самое простое решение состоит в предварительном ПЭНД нули

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 

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

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

+0

Почему бы не поставить «0000000002» на «000000001a»? –

+0

@ Эрик Робертсон - Пересмотрено мое сообщение. У меня не было шанса полностью выжить в первый раз. – Thomas

+0

Это, безусловно, не похоже на самое простое решение. :) –

1

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

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

+0

почтительно, я должен не согласиться. Там должен быть лучший способ. Мне нравится решение здесь, оно работает. В качестве альтернативы, я бы тоже пошел с предложением @ Rob. – SoftwareGeek

+0

@SoftwareGeek - лучший способ сделать это - это способ, которым вы можете воспользоваться базами данных. Конечно, если у вас нет доступа к изменению базы данных, то лучшего решения не может быть и речи. Разработчик базы данных должен был понять, что люди захотят получить данные в этом методе и спроектированы соответствующим образом. –

2

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

+0

yes, v.good suggestion, но если db может выполнить задачу, тогда я позволю ей обработать ее. – SoftwareGeek

+0

@SoftwareGeek, я получаю то, что вы говорите, но ... ... CLR-функции в значительной степени «хороши», как TSQL, одни из лучших, и никогда не бывает плохо иметь другой инструмент, особенно тот, который лучше подходит для заданная задача =) – Rob