如何编写T-SQL查询以按字母顺序对列进行排序,并将结束编号作为数值?
换句话说,我不会考虑可能位于字符串中间的数字,以简化问题。
以示例:
a1XBNR1
a1XBNR10 <-- this should go after a1BRN2
a1XBNR2
这是一个无法正确排序的示例代码:
-- Alphanumeric sorting with T-SQL
USE [AdventureWorks2012]
GO
CREATE TABLE dbo.TestTable
(
id varchar(50) NULL
)
DELETE dbo.TestTable
GO
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XANR1')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XANR10')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XANR2')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XANR20')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XANR3')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XB11')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('a1XB2')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('b1XBNR20')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('b1XB30')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('b1XB2')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('AB100')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('1')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('AB1')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('A1')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B2')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('A11')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B20')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B21')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('AB10')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B3')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('AB100')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('2')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B1')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('B32')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('11')
INSERT INTO dbo.TestTable (TestTable.id) VALUES ('A10')
-- Attempt 1 - Syntax not supported by T-SQL
SELECT *
FROM db.TestTable
ORDER BY left(id, 1) -- 1st letter as text
, substring(fest, '\d+')::int NULLS FIRST -- first number in string as int
, id -- whole columns as cheap tiebreaker
-- Attempt 2 - cannot have digit in the middle of the string
-- Error: Conversion failed when converting the varchar value '1XBNR1' to data type int.
SELECT id
FROM dbo.TestTable
ORDER BY LEFT(id,PATINDEX('%[0-9]%',id)-1), -- alphabetical sort
CONVERT(INT,SUBSTRING(id,PATINDEX('%[0-9]%',id),LEN(id))) -- numerical
答案 0 :(得分:3)
在尾随数字前面的左边部分使用patindex()
和reverse()
顺序,并将最后一组数字转换为其余部分的整数。
select *
from testtable t
order by
left(id,len(id)-patindex('%[^0-9]%',reverse(id))+1)
, convert(int,right(id,patindex('%[^0-9]%',reverse(id)+' ')-1))
rextester演示:blog post at this link
返回:
+----------+
| id |
+----------+
| 1 |
| 11 |
| 2 |
| A1 |
| A10 |
| A11 |
| a1XANR1 |
| a1XANR2 |
| a1XANR3 |
| a1XANR10 |
| a1XANR20 |
| a1XB2 |
| a1XB11 |
| AB1 |
| AB10 |
| AB100 |
| AB100 |
| B1 |
| B2 |
| B3 |
| B20 |
| B21 |
| B32 |
| b1XB2 |
| b1XB30 |
| b1XBNR20 |
+----------+