按字符串包含的数字对字符串的自然顺序进行排序

Collation for the natural order of strings by a number they contain

Note: I believe this is no duplicate of this seemingly related question, since I’ve got actual strings that contain a number instead of integers stored as strings like the other OP.

我正在寻找一种方法来输出 SQL 字符串,这些字符串按它们包含的数字以自然顺序排序,例如数字中缀。例如,Windows Explorer 自然而然地这样做:

On DBA,我读到数字本身没有按字母排序的属性, 但我确信对于不带前导零的中缀数字,有一些方法可以做到这一点,因为它们很重要。

在SQLServer 2008 R2中,我的场景有点像这样:

DECLARE @Table TABLE (ID INT, Name VARCHAR(10));
INSERT INTO @Table (ID, Name) VALUES
(1,'name1file'),   (5,'name11file'),
(2,'name2file'),   (6,'name20file'),
(3,'name3file'),   (7,'name21file'),
(4,'name10file');
SELECT * FROM @Table ORDER BY Name COLLATE Latin1_General_100_BIN ASC;

示例结果集:

 Output got         Output desired
 ID | Name          ID | Name
 ==========         ==========
 1  | name1file     1  | name1file
 4  | name10file    2  | name2file
 5  | name11file    3  | name3file
 2  | name2file     4  | name10file
 6  | name20file    5  | name11file
 7  | name21file    6  | name20file
 3  | name3file     7  | name21file

ID 列仅用于说明目的(在这种情况下您可以只 ORDER BY ID)。它只是我查询的 VARCHAR 列。我尝试使用 COLLATE, but none of the fn_helpcollations 我尝试生成所需的订单。

那么,有没有一种方法可以在不使用的情况下使用SUBSTRINGPATINDEX或CLR函数或其他提取方法来实现数字,也许通过使用适当的排序规则?

如果不是,是否有原因没有在数千个归类中的任何一个中实现这个常见用例?我希望 Windows Explorer 为此使用一些通用的排序规则,而不是像 PHP 的 natsort().

这样的函数实现

如果您的文件名称格式为 name###file,您可以使用

对其进行排序

SELECT * FROM @Table ORDER BY LEN(Name), Name

这个排序很简单,先按姓名长度排序,再按姓名排序。您的文件名是不变的,只有数字部分发生了变化,因此“5”、“1”和“2”是基于长度的 "before "10”。第二次排序给出了相同大小(0-9)的数字之间的正确顺序) (10-99) (100-999) 等等。

请记住,它不是完美的通用解决方案,例如:"z" < "aa".