按字符串包含的数字对字符串的自然顺序进行排序
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
我尝试生成所需的订单。
那么,有没有一种方法可以在不使用的情况下使用SUBSTRING
或PATINDEX
或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".
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
我尝试生成所需的订单。
那么,有没有一种方法可以在不使用的情况下使用SUBSTRING
或PATINDEX
或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".