包含字符和字符串的SQL顺序

时间:2013-09-28 10:24:30

标签: sql sql-server

我有一张桌子,我想要colum joint_no列。列的值类似于

FW-1 
FW-2
.
.
.
FW-13
FW-R1
FW-1A

当我订购它时,我得到了这个结果

FW-1
FW-10
FW-11
FW-12
FW-13
FW-1A
.
.
FW-R1

我想在sql查询

之后得到这个结果
FW-1
FW-1A
FW-2
FW-3
..
FW-13
FW-R1

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:2)

如果你能做到这一点,我建议你重新编号,使'逻辑'顺序符合字母顺序。然后F-1将更新为F-01或F-001。

如果您不能这样做,请添加一个将填充代码的“有序”形式的字段。然后,您将能够通过F-001列进行订购,并仍然显示F-1值

否则订购您的记录将很快成为您的噩梦。

答案 1 :(得分:0)

使用Patindex查找第一个数字表达式作为第一个排序字段,然后将数字部分提取为整数作为第二个排序字段,并使用整个字符串作为第三个排序字段,您可能会得到所需的结果。

Declare @a Table (c varchar(50))
Insert Into @a
Select 'FW-1'
Union Select 'FW-10'
Union Select 'FW-11'
Union Select 'FW-12'
Union Select 'FW-13'
Union Select 'FW-1A'
Union Select 'FW-2'
Union Select 'FW-3'
Union Select 'FW-R1'
Union Select 'FW-A1'
;With CTE as
(Select 1 as ID
Union All
Select ID + 1 from CTE where ID < 100
)

Select * from
(
Select c
 ,PATINDEX('%[0-9]%',c) as s1
 ,(Select Cast(
          (Select Case
                   When SUBSTRING(c, ID, 1) LIKE '[0-9]'
                   Then SUBSTRING(c, ID, 1)
                   Else ''
                  End
          From (Select * from CTE) AS X(ID)
          Where ID <= LEN(c)
          For XML PATH('')) 
          as int)
   )
  as s2
 from
@a
) x
order by
s1,s2,c

输出:

FW-1    4   1   -1
FW-1A   4   1   -1A
FW-2    4   2   -2
FW-3    4   3   -3
FW-10   4   10  -10
FW-11   4   11  -11
FW-12   4   12  -12
FW-13   4   13  -13
FW-A1   5   1   A1
FW-R1   5   1   R1

如果未固定前导部分(FW-),则可能需要添加一个额外的排序字段

Declare @a Table (c varchar(50))
Insert Into @a
Select 'FW-1'
Union Select 'FW-10'
Union Select 'FW-11'
Union Select 'FW-12'
Union Select 'FW-13'
Union Select 'FW-1A'
Union Select 'FW-2'
Union Select 'FW-3'
Union Select 'FW-R1'
Union Select 'FW-A1'
Union Select 'AB-A1'
Union Select 'AB-11'
;With CTE as
(Select 1 as ID
Union All
Select ID + 1 from CTE where ID < 100
)

Select * from
(
Select c
 ,SubString(c,1,PATINDEX('%[0-9]%',c)-1) as S0
 ,PATINDEX('%[0-9]%',c) as s1
 ,(Select Cast(
          (Select Case
                   When SUBSTRING(c, ID, 1) LIKE '[0-9]'
                   Then SUBSTRING(c, ID, 1)
                   Else ''
                  End
          From (Select * from CTE) AS X(ID)
          Where ID <= LEN(c)
          For XML PATH('')) 
          as int)
   )
  as s2
 from
@a
) x
order by
s0,s1,s2,c