Sql server 如何对SQL Server中包含ABC、ABC123123等数据的Varchar字段进行排序

Sql server 如何对SQL Server中包含ABC、ABC123123等数据的Varchar字段进行排序,sql-server,Sql Server,我有一个部分列,它是一个varchar,我试图对它进行排序,得到如下所示的结果 Section ------- 1 100 11 180a 18a 18b 19B 2 A1 A10 A11 A18 A180 A189 A19 A1B AB1 AB10 AB100 Aquaman B1 B2 B20 B21 B3 B32 S Superman 我希望结果如下。首先我得到升序排列的数

我有一个部分列,它是一个varchar,我试图对它进行排序,得到如下所示的结果

Section  
-------
1  
100  
11  
180a  
18a  
18b  
19B  
2  
A1  
A10  
A11  
A18  
A180  
A189  
A19  
A1B  
AB1  
AB10  
AB100  
Aquaman  
B1  
B2  
B20  
B21  
B3  
B32  
S  
Superman  
我希望结果如下。首先我得到升序排列的数字,然后是alpha数值,最后是char值

如果先是字符值,然后是字母数字,然后是数字,这就不会成为问题

Section
-------
1  
2  
11  
100  
18a  
18b  
19B  
180a  
A1  
A10  
A11  
A18  
A19  
A180  
A189  
A1B  
AB1  
AB10  
AB100  
B1  
B2  
B20  
B21  
B3  
B32  
Aquaman  
S  
Superman  
我尝试了下面的查询,在某种程度上接近了我的期望,但并不完全符合我的期望

SELECT Section
FROM dbo.Section_suw
ORDER BY
case  when ISNUMERIC(Section)=0 then Section else '0' end,
case when ISNUMERIC(Section)=1 then CONVERT(INT, Section) else -1 end
用于测试目的的演示表

CREATE TABLE dbo.Section_suw
(
       Section varchar(50) NULL
)

INSERT INTO dbo.Section_suw (Section.Section) VALUES ('1')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('AB1')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A1')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B2')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A11')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B20')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B21')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('AB10')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B3')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('AB100')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('2')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B1')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('B32')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('11')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A10')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A1B')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A180')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A189')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('180a')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('18a')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('18b')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A18')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('A19')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('19B')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('100')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('Superman')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('Aquaman')
INSERT INTO dbo.Section_suw (Section.Section) VALUES ('S')

提前感谢

只要您使用的是支持TRY\u CAST(2012年以后)的SQL Server版本,此功能就可以正常工作


只要您使用的是支持TRY\u CAST(2012年以后)的SQL Server版本,此功能就可以正常工作

试试这个

SELECT Section FROM dbo.Section_suw
ORDER BY
case when ISNUMERIC(Section)=0  then  iif(PATINDEX('%[0-9]%',Section)>0,Section,'z'+Section) else '0' end
试试这个

SELECT Section FROM dbo.Section_suw
ORDER BY
case when ISNUMERIC(Section)=0  then  iif(PATINDEX('%[0-9]%',Section)>0,Section,'z'+Section) else '0' end


通常,维护一个既需要作为文本又需要作为数字的列是一个坏主意。相反,我建议将文本和数字部分保留在单独的列中。就像可口可乐和百事可乐;你永远不会同时拥有两个罐子。
S
为什么出现在
Superman
之后?你是@TimBiegeleisen当我看到这个专栏时,我也有同样的想法,它是地址专栏的一部分,似乎这个专栏必须有数字和字符,有时只有数字,有时只有字符在我的情况下,我被困于此列,因为我正在处理一个构建良好的数据库(oops@GMB….我刚才注意到了….我没有编辑的选项….或者让我看看我是否可以编辑这个问题。我能看到这个可行的唯一方法是将数字部分和非数字部分分开,然后对它们进行排序。如果你有一个数字部分,那么一个数字部分不会太乱,但是,如果你有一个have like
'1B9A'会很混乱。通常情况下,维护一个既需要作为文本又需要作为数字的列是一个坏主意。相反,我建议将文本和数字部分保留在单独的列中。这就像可口可乐和百事可乐;你永远不会同时拥有两个罐头。为什么
s
出现在
超人
之后re@TimBiegeleisen当我看到这个专栏时,我也有同样的想法,它是address专栏的一部分,似乎这个专栏必须有数字和字符,有时只有数字,有时只有字符。在我的例子中,我被这个专栏困住了,因为我正在处理一个构建良好的数据库(oops@GMB….我刚才注意到了….我没有编辑的选项….或者让我看看我是否可以编辑这个问题。我能看到这个可行的唯一方法是将数字部分和非数字部分分开,然后对它们进行排序。如果你有一个数字部分,那么一个数字部分不会太乱,但是,如果你有一个have like
'1B9A'这会很混乱。但是,这不会对
'A180'
之前的
'A19'
'A2'
这样的值进行排序吗?您的解决方案会对
180a
之前的
18a
进行排序。好了,所以我尝试了这个
从dbo中选择节。\u按大小写排序,当是数字时(节)=0,然后是iif(PATINDEX)('[0-9]',Section)>0,节,'z'+节)否则“0”结束,当ISNUMERIC(节)=1时,则转换(INT,节)else-1 end
result=除了18a之前的180a之外,我得到了所有预期的结果。但是,这不是吗,在
'A19'
之前对
'A180'
'A2'
这样的值进行排序吗?您的解决方案在
18a
之前对
180a
进行排序。好了,所以我尝试了这个
从dbo中选择节。当节是数字时,请按大小写顺序排序(Section)=0然后iif(PATINDEX('%[0-9]]',Section)>0,Section,'z'+Section)否则'0'结束,当是数字时,case(Section)=1然后CONVERT(INT,Section)else-1结束
result=除了18aok之前的180a之外,我得到了所有预期结果,所以我尝试了这个
从dbo中选择Section.Section\suw按大小写顺序当是数字时(Section)=0然后iif(PATINDEX('%[0-9]]',Section)>0,Section,'z'+Section)否则'0'结束,如果是数字(Section)=1,则转换(INT,Section)else-1结束
在结果中,除
18a
之前的
180a
确定外,我尝试了这个
从dbo中选择Section=0然后iif(PATINDEX('%[0-9]]',Section)>0,Section,'z'+Section)否则'0'结束,如果ISNUMERIC(Section)=1,则转换(INT,Section)else-1结束,结果是除
18a