我有一个varchar列来讨论代码,这个代码只能通过数字,或者以char作为前缀的数字,例如我有一个包含这些数据的列:
+------+
| 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。
答案 0 :(得分:4)
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
答案 1 :(得分:3)
假设值之前没有空格,并且只能有1个字符前缀:
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个字符,要么不删除,即与先前相同。
答案 2 :(得分:0)
...ORDER by ('A'+Code)
答案 3 :(得分:0)
SELECT Code FROM Code_List ORDER BY Code, CASE WHEN ISNUMERIC(SUBSTRING(Code,1,1)) = 1 THEN CODE ELSE SUBSTRING(Code,2,LEN(Code)-1) END
显然假设只有第一个数字可以是alpha