1
1one
2
2two
11
11eleven
11
22twentytwo
111oneeleven
552
3311
A1
A10
A11
A100
AB1
AB10
AB10A
AB100
AB100
B1
B2
B3
B3
B20
B20BB
B21BC
B21
B32
我想在下面的排序顺序中列出上面的列表。
1
2
11
11
552
3311
1one
2two
11eleven
22twentytwo
111oneeleven
A1
A10
A11
A100
AB1
AB10
AB10A
AB100
AB100
B1
B2
B3
B3
B20
B20BB
B21BC
B21
B32
查询是:
SELECT
Section,
LEFT(Section, PATINDEX('%[0-9]%', Section) - 1) AS left1,
PATINDEX('%[0-9]%', Section) startindex,
LEN(Section) AS length,
PATINDEX('%[0-9]%', REVERSE(Section)) AS revindex,
LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 positionofendint,
SUBSTRING(Section, PATINDEX('%[0-9]%', Section), LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1) integerpart,
LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 - PATINDEX('%[0-9]%', Section) + 1 subintlength,
ISNUMERIC(section) isnumeric1,
LEFT(Section, PATINDEX('[0-9]', Section)) onlyint
FROM
dbo.Section
WHERE
section NOT IN ('33A100', '55B32', '55B1', '55AB100', '99AB10A', '99B21BC', '1B20BB', '6B2B', '3AB1', '4a1', '7A11', '99B3')
--where section not like '%B%' and section not like '%A%' and section not like '%o%' and section not like '%e%'
--ORDER BY section
--, CONVERT(INT,(case when isnumeric(section)=1 then section end))
ORDER BY
LEFT(Section, PATINDEX('%[0-9]%', Section) - 1), -- alphabetical sort
CONVERT(INT, SUBSTRING(Section, PATINDEX('%[0-9]%', Section),
LEN(Section) - PATINDEX('%[0-9]%', REVERSE(Section)) + 1 - PATINDEX('%[0-9]%', Section) + 1)) -- numerical sort
在这里,以字母开头的Word正在排序,旁边的数字也在排序,但是以数字开头的单词没有排序,请帮我解释如何用字符对单词的起始数字进行排序。
答案 0 :(得分:1)
也许是一个简单的案例陈述?这并不特别匹配您的结果,但它正确地对varchar部分进行排序,在(可能是)和整数部分之后。
declare @table table (v varchar(64))
insert into @table
values
('1'),
('1one'),
('2'),
('2two'),
('11'),
('11eleven'),
('11'),
('22twentytwo'),
('111oneeleven'),
('552'),
('3311'),
('A1'),
('A10'),
('A11'),
('A100'),
('AB1'),
('AB10'),
('AB10A'),
('AB100'),
('AB100'),
('B1'),
('B2'),
('B3'),
('B3'),
('B20'),
('B20BB'),
('B21BC'),
('B21'),
('B32')
select v
from @table
order by case when v like '%[^0-9]%' then v end, v
答案 1 :(得分:1)
我相信你所追求的CASE
是这样的:
SELECT Section
FROM dbo.Section
ORDER BY
--Primary sort puts results that start with a letter to the end
--Otherwise, sorts by where the occurrence of the first letter is
CASE PATINDEX('%[^0-9]%', Section) WHEN 1 then 99 ELSE PATINDEX('%[^0-9]%', Section) END,
--Secondary sort will sort numeric values by length instead of number
CASE PATINDEX('%[^0-9]%', Section) WHEN 1 then 99 ELSE LEN(Section) END,
--Final sort alpha-numeric
Section
(感谢scsimon,他answer编写了测试此表所需的表创建。)
编辑:上面的查询会让您关闭,但字母数字排序有问题。它会在AB100
(等)之前返回AB10A
,会更深入地查看。
答案 2 :(得分:0)
尝试这样......
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL
DROP TABLE #TestData;
SELECT
x.SomeValue
INTO #TestData
FROM
( VALUES
('1'), ('1one'), ('2'), ('2two'), ('11'), ('11eleven'), ('11'), ('22twentytwo'), ('111oneeleven'),
('552'), ('3311'), ('A1'), ('A10'), ('A11'), ('A100'), ('AB1'), ('AB10'), ('AB10A'), ('AB100'),
('AB100'), ('B1'), ('B2'), ('B3'), ('B3'), ('B20'), ('B20BB'), ('B21BC'), ('B21'), ('B32')
) x (SomeValue);
SELECT
td.SomeValue
FROM
#TestData td
ORDER BY
CASE WHEN td.SomeValue NOT LIKE '%[^0-9]%' THEN CAST(td.SomeValue AS INT) ELSE 2147483647 END,
CASE WHEN LEFT(td.SomeValue, 1) BETWEEN '0' AND '9' AND td.SomeValue LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeValue, 1, PATINDEX('%[^0-9]%', td.SomeValue) - 1) AS INT) ELSE 2147483647 END,
td.SomeValue;
HTH,Jason