Jus*_*ing 12 sql-server collation sorting natural-sort
我有一个包含不同长度整数的 VARCHAR 列的数据库。我想对它们进行排序,所以 10 在 9 之后,而不是 1,并且 70A 在 70 之后。我可以使用WHERE 子句中的PATINDEX()、CTE 和 CASE 语句来做到这一点。
但是,我想知道是否有不需要的整理。
不。整理是关于字母排序,取决于代码页、重音、大小写、宽度、假名。数字字符 (0-9) 没有任何属性。
所以9
总是10B
在任何形式之后。
您必须按照您的说明将其拆分或按以下方式排序:
ORDER BY
RIGHT(' ' + MyColumn, 30)
Run Code Online (Sandbox Code Playgroud)
右边的长度决定了你有多少空间。
你当然可以:
后 2 个建议与我上面的权利相似,但略有不同。排序更快(无需处理 colukmn)但需要更多存储空间
我会设置一个计算列,然后根据它进行排序。就像是
CAST(
CASE WHEN IS_NUMERIC(left(OtherColumn, 2) = 1) then
left(OtherColumn,2)
else
left(otherColumn, 1)
AS INT)
Run Code Online (Sandbox Code Playgroud)
然后使用此列进行排序,因为您现在可以索引该列。
如果您想要一种痛苦的方式来证明@gbn 所说的内容(本质上是您不能告诉排序规则以不同的方式对子字符串进行排序),您可以制作一个快速的#temp 表,该表具有您期望的顺序的系数,看看是否按任何排序规则排序返回相同的顺序:
CREATE TABLE #foo(id INT, n NVARCHAR(10));
CREATE TABLE #bar(collation SYSNAME);
SET NOCOUNT ON;
INSERT #foo SELECT 1,'1'
UNION SELECT 2,'2'
UNION SELECT 3,'3'
UNION SELECT 4,'6'
UNION SELECT 5,'10'
UNION SELECT 6,'10A'
UNION SELECT 7,'10B'
UNION SELECT 8,'11';
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += N'
WITH x AS
(
SELECT n, rn = ROW_NUMBER() OVER
(ORDER BY n COLLATE ' + name + ') FROM #foo
)
INSERT #bar
SELECT TOP (1) ''' + name + ''' FROM x
WHERE NOT EXISTS
(
SELECT COUNT(*) FROM #foo AS f
WHERE f.id = x.rn
AND f.n <> x.n
);' FROM sys.fn_helpcollations();
EXEC sp_executesql @sql;
SELECT collation FROM #bar;
GO
DROP TABLE #foo, #bar;
Run Code Online (Sandbox Code Playgroud)
这会在大约 10 秒内为我运行并产生 0 行 - 这意味着 SQL Server 没有可用的排序规则(至少 2008 R2,还没有尝试过 Denali)将按照您期望的方式进行排序。您需要一种不同的方式来定义排序。
归档时间: |
|
查看次数: |
2900 次 |
最近记录: |