2

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

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

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

但我需要它

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

更新

好的,我在建议之后这样做,但它不起作用。

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'

更新2

它在进行以下更改后起作用。

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

感谢大家的好主意。

4

3 回答 3

9

最简单的解决方案是预置零

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

关于我的解决方案的说明。如果字母字符具有特殊含义,那么正如 Erick Robertson 建议的那样,您应该将数据分成单独的列。上述解决方案将只处理两种非常具体的情况:一个全数字值,一个带有单个尾随字母字符的值。如果数据可能有多个字母字符,或者字母字符有时位于值的末尾以外,我的解决方案将不起作用。此外,应该注意的是,我的解决方案将导致表扫描来评估每个值的可排序字符串。

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

于 2010-07-24T18:42:44.947 回答
2

如果您熟悉 C# 或 VB.net,则可能值得考虑编写一个 CLR 函数来为您执行排序,因为这种排序顺序是非标准的,很难在 TSQL 中全面和正确地描述。

于 2010-07-24T18:57:21.757 回答
1

最好的解决方案是有一个单独的字段来存储令牌的 int 值。当您维护令牌列时,您应该维护此列。然后,当您排序时,按 int value 列排序,然后按 token 列排序。这将允许您对这些列进行索引,以便快速检索具有大型数据集的数据。

从 alpha 到 int 的转换函数很慢,并且不能利用索引来加速查询。随着您的数据集的增长,这种类型的解决方案只会变得更慢并让您的数据库陷入困境。

于 2010-07-24T18:47:13.860 回答