T-Sql - 按字母数字排序

Sof*_*eek 2 t-sql alphanumeric sql-order-by sql-server-2008

我有一个字母数字标记列表,比如说'1a', '1b', '02', '03', '10', '11',...

现在,在这个令牌列表上执行订单的最佳方式是什么?

我正进入(状态 '1a', '1b', '10', '11', '02', '03',

但我需要它

'1a', '1b', '02', '03', '10', '11' 
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

我收到了回复 '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
Run Code Online (Sandbox Code Playgroud)

感谢大家的好主意.

Tho*_*mas 8

最简单的解决方案是预先添加零

Select ...
From Table
Order By Right( '0000000000' + YourColumn, 10)
Run Code Online (Sandbox Code Playgroud)

但是,这不会考虑字母字符.为了处理字母字符,您需要知道可能有多少潜在的字母字符.如果有,你可以这样做:

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

加成

测试运行:

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
Run Code Online (Sandbox Code Playgroud)

关于我的解决方案的说明.如果是字母字符具有特殊含义的情况,那么正如Erick Robertson所建议的那样,您应该将数据分解为单独的列.上述解决方案仅处理两种非常特殊的情况:全数字值,具有单个尾随字母字符的值.如果数据可能包含多个字母字符,或者字母字符有时位于值的末尾以外,则我的解决方案将无效.此外,应该注意的是,我的解决方案将导致表扫描以评估每个值上的可订单字符串.

如果您寻求的是一次性快速解决方案,那么我的方法将起作用.如果您正在寻求长期解决方案,那么要么将数据分解为单独的列,接受愚蠢的排序顺序,要么添加一个列来指示每个值的相对排序顺序.