Sql 顺序/排序列混合数字和以字符为前缀的数字

Sql 顺序/排序列混合数字和以字符为前缀的数字,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有一个与代码相关的varchar列,该代码只能由数字或以字符为前缀的数字组成。例如,我有一个包含以下数据的列: +------+ | Code | +------+ | 1 | | C1 | | 2 | | 3 | | C3 | | F3 | | F1 | | F17 | | C9 | | C10 | | C47 | | C100 | | C134 | | A234 | |C1245 | | 10 | | 100 | +------+ 等等

我有一个与代码相关的varchar列,该代码只能由数字或以字符为前缀的数字组成。例如,我有一个包含以下数据的列:

+------+
| Code |
+------+
|  1   |
|  C1  |
|  2   |
|  3   |
|  C3  |
|  F3  |
|  F1  |
|  F17 |
|  C9  |
|  C10 |
|  C47 |
| C100 |
| C134 |
| A234 |
|C1245 |
|   10 |
|  100 |
+------+
等等

我想按以下规则对该列进行排序:

  • 仅数字代码
  • 前缀代码,字母部分顺序为数字,数字部分顺序为数字
  • 我希望实现如下排序的结果集:

    +------+
    | Code |
    +------+
    |  1   |
    |  2   |
    |  3   |
    | 10   |
    | 100  |
    | A234 |
    |  C1  |
    |  C3  |
    |  C9  |
    |  C10 |
    |  C47 |
    | C100 |
    | C134 |
    |C1245 |
    |  F1  |
    |  F3  |
    |  F17 |
    +------+
    
    如何获得按此条件排序的结果集? 我尝试过这样的查询:

    SELECT Code FROM Code_List ORDER BY case when Code like '%[a-z]%' then 99999999999999999999999999999999 else convert(decimal, Code) end
    
    但我得到的结果是,先对数字排序,然后对前缀数字排序,但alpha前缀数字的排序像char一样,而不是我想要的方式

    唯一的数字记录应按照数字顺序规则进行排序,而不是字符顺序,因此,如果唯一的数字记录是:

    +------+
    | Code |
    +------+
    |  1   |
    |  47  |
    |  2   |
    |  3   |
    |  6   |
    |  100 |
    |  112 |
    |  10  |
    
    我想得到:

    +------+
    | Code |
    +------+
    |  1   |
    |  2   |
    |  3   |
    |  6   |
    |  10  |
    |  47  |
    |  100 |
    |  112 |
    
    数据库是Microsoft SQL Server。

    您可以试试

    ...ORDER by ('A'+Code)
    

    显然,假设只有第一个数字可以是alpha

    假设值之前没有空格,并且只能有1字符前缀:

     CASE
        WHEN ISNUMERIC(Col) = 1 THEN '@'
        Else LEFT(Col, 1)
     END
    ,CASE
        WHEN ISNUMERIC(Col) = 1 THEN Convert(int, Col)
        Else Convert(int, RIGHT(Col, LEN(Col) - 1))
     END
    
    ORDER BY
      CASE WHEN LEFT(Code, 1) BETWEEN '0' AND '9' THEN ' ' ELSE LEFT(Code, 1) END,
      CAST(STUFF(Code, 1, CASE WHEN LEFT(Code, 1) BETWEEN '0' AND '9' THEN 0 ELSE 1 END, '') AS int)
    
    或者,第二个标准可以这样重写:

      CAST(STUFF(Code, 1, PATINDEX('[^0-9]%', Code), '') AS int)
    

    PATINDEX(“[^0-9]]”,code)
    如果在
    code
    开头发现非数字字符,则返回1,否则返回0。因此,
    STUFF
    要么删除1个字符,要么一个字符都不删除,即与以前相同。

    这是假设数字前没有空格……如果是这样,您可能需要修剪“code”值……这不符合op想要的第二条规则。您的代码上可以有多个字母吗?,它总是在第一个字符上吗?我也可以有多个字母作为前缀,但该字母只能在前缀中,因此我可以有一个字符作为前缀,也可以有两个字符作为前缀。如果是数字(Col+'.0e0',您可能需要执行
    如果规则发生变化,允许数字作为字符的前缀。前缀数字的顺序正确,但唯一的数字没有。如果我有一个10和一个100的get:1,10100,3,4,唯一的数字是按字符规则排序的,我希望它按数字规则排序,那么结果应该是:1,3,4,10100。@amit\u g:我试过转换(int,Col)和转换(Col AS int),但结果总是按字符排序,而不是按数字排序。。。不起作用。@aleroot-我的解决方案正确地处理了这个场景,我用你在这里提到的这个测试用例更新了它(见下面的答案)。@dcp:我试过了,但没有正常工作,我在100和112之后得到47,数字部分的顺序不是数字顺序。。
      CAST(STUFF(Code, 1, PATINDEX('[^0-9]%', Code), '') AS int)