Sql Server 2008 中的字母数字排序
Alphanumeric Sorting in Sql Server 2008
谁能帮我解决这个问题?
我有一个要排序的动态模式列表,它包含字母数字值和字母。
CREATE TABLE dbo.Pattern (Pattern varchar(50) NULL)
INSERT INTO dbo.Pattern (Pattern) VALUES ('A11')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A12')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A8')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B6')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B21')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B10')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B3')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B100')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A20')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AB')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BB')
SELECT Pattern FROM dbo.Pattern ORDER BY Pattern
DROP Table dbo.Pattern
结果是这样的:
A11
A12
A2
A20
A8
AA
AB
B10
B100
B2
B21
B3
B6
BA
BB
但我想展示的是这样的结果:
AA
A1
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB
对于您的样本数据,这很接近:
order by left(pattern, patindex('%[0-9]%', pattern)),
patindex('%[0-9]%', pattern),
len(pattern) asc,
pattern
但是,您希望所有 alpha 都在最后,因此需要 case
(我认为):
order by left(pattern, patindex('%[0-9]%', pattern)),
(case when pattern like '%[0-9]%'
then patindex('%[0-9]%', pattern)
else 999
end),
len(pattern) asc,
pattern
SELECT Pattern
FROM dbo.Pattern
ORDER BY CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1)
ELSE Pattern
END,
CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
THEN CONVERT(INT, SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)))
ELSE 0
END
发帖前请先搜索网络和 Stack Overflow。
参考: http://www.essentialsql.com/use-sql-server-to-sort-alphanumeric-values/
我会分开 alpha 和 num 部分:
ORDER BY
CASE WHEN PATINDEX('%[0-9]%', Pattern)=0 THEN 1 ELSE 0 END,--Put no-nums last
CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) ELSE Pattern END,
CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)) END
使用交叉应用来简化行内计算
select pattern
from pattern
cross apply (
select leftLen = isnull(nullif(patindex('%[0-9]%', pattern),0) - 1, len(pattern))
,totalLen = len(pattern)
) c
order by
case leftLen when totalLen then 2 else 1 end,
left(Pattern, leftLen),
cast(right(Pattern, totalLen-leftLen) as int)
SELECT Pattern
FROM dbo.Pattern
ORDER BY LEFT(Pattern,1),
CASE WHEN SUBSTRING(Pattern,2,LEN(Pattern)) LIKE '%[0-9]%' THEN CAST(SUBSTRING(Pattern,2,LEN(Pattern)) as int)
WHEN SUBSTRING(Pattern,2,LEN(Pattern)) = 'A' THEN 0
ELSE 10000000 END,
SUBSTRING(Pattern,2,LEN(Pattern))
将输出:
Pattern
AA
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB
谁能帮我解决这个问题?
我有一个要排序的动态模式列表,它包含字母数字值和字母。
CREATE TABLE dbo.Pattern (Pattern varchar(50) NULL)
INSERT INTO dbo.Pattern (Pattern) VALUES ('A11')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A12')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A8')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B6')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B21')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B10')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B3')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B100')
INSERT INTO dbo.Pattern (Pattern) VALUES ('B2')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BA')
INSERT INTO dbo.Pattern (Pattern) VALUES ('A20')
INSERT INTO dbo.Pattern (Pattern) VALUES ('AB')
INSERT INTO dbo.Pattern (Pattern) VALUES ('BB')
SELECT Pattern FROM dbo.Pattern ORDER BY Pattern
DROP Table dbo.Pattern
结果是这样的:
A11
A12
A2
A20
A8
AA
AB
B10
B100
B2
B21
B3
B6
BA
BB
但我想展示的是这样的结果:
AA
A1
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB
对于您的样本数据,这很接近:
order by left(pattern, patindex('%[0-9]%', pattern)),
patindex('%[0-9]%', pattern),
len(pattern) asc,
pattern
但是,您希望所有 alpha 都在最后,因此需要 case
(我认为):
order by left(pattern, patindex('%[0-9]%', pattern)),
(case when pattern like '%[0-9]%'
then patindex('%[0-9]%', pattern)
else 999
end),
len(pattern) asc,
pattern
SELECT Pattern
FROM dbo.Pattern
ORDER BY CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1)
ELSE Pattern
END,
CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0
THEN CONVERT(INT, SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)))
ELSE 0
END
发帖前请先搜索网络和 Stack Overflow。
参考: http://www.essentialsql.com/use-sql-server-to-sort-alphanumeric-values/
我会分开 alpha 和 num 部分:
ORDER BY
CASE WHEN PATINDEX('%[0-9]%', Pattern)=0 THEN 1 ELSE 0 END,--Put no-nums last
CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) ELSE Pattern END,
CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)) END
使用交叉应用来简化行内计算
select pattern
from pattern
cross apply (
select leftLen = isnull(nullif(patindex('%[0-9]%', pattern),0) - 1, len(pattern))
,totalLen = len(pattern)
) c
order by
case leftLen when totalLen then 2 else 1 end,
left(Pattern, leftLen),
cast(right(Pattern, totalLen-leftLen) as int)
SELECT Pattern
FROM dbo.Pattern
ORDER BY LEFT(Pattern,1),
CASE WHEN SUBSTRING(Pattern,2,LEN(Pattern)) LIKE '%[0-9]%' THEN CAST(SUBSTRING(Pattern,2,LEN(Pattern)) as int)
WHEN SUBSTRING(Pattern,2,LEN(Pattern)) = 'A' THEN 0
ELSE 10000000 END,
SUBSTRING(Pattern,2,LEN(Pattern))
将输出:
Pattern
AA
A2
A8
A11
A12
A20
AB
BA
B2
B3
B6
B10
B21
B100
BB