让我们从 Microsoft 给出的这些类型的定义开始(摘自CompareOptions Enumeration MSDN 页面的“备注”部分):
.NET Framework 使用三种不同的排序方式:单词排序、字符串排序和序数排序。 Word 排序对字符串执行区分区域性的比较。某些非字母数字字符可能具有分配给它们的特殊权重。例如,连字符(“-”)可能分配给它的权重非常小,因此“coop”和“co-op”在排序列表中彼此相邻出现。字符串排序类似于单词排序,只是没有特殊情况。因此,所有非字母数字符号都位于所有字母数字字符之前。序数排序根据字符串中每个元素的 Unicode 值比较字符串。
Unicode 具有文化敏感性和权重,XML 和 N 前缀类型是 Unicode,因此他们可能会说 Unicode 类型中的数据使用“字排序”,而非 Unicode 类型中的数据使用“字符串排序”。 Ordinal 指的是BIN 和BIN2 排序规则,尽管BIN 排序规则不是100% 的排序规则,因为它们处理第一个字符的方式。
但是让我们看看 SQL Server 说它在做什么。运行以下命令:
DECLARE @SampleData TABLE (ANSI VARCHAR(50), UTF16 NVARCHAR(50));
INSERT INTO @SampleData (ANSI, UTF16) VALUES
('a-b-c', N'a-b-c'),
('ac', N'ac'),
('aba', N'aba'),
('a-b', N'a-b'),
('ab', N'ab');
SELECT sd.ANSI AS [ANSI-Latin1_General_100_CI_AS]
FROM @SampleData sd
ORDER BY sd.ANSI COLLATE Latin1_General_100_CI_AS ASC;
SELECT sd.UTF16 AS [UTF16-Latin1_General_100_CI_AS]
FROM @SampleData sd
ORDER BY sd.UTF16 COLLATE Latin1_General_100_CI_AS ASC;
SELECT sd.ANSI AS [ANSI-SQL_Latin1_General_CP1_CI_AS]
FROM @SampleData sd
ORDER BY sd.ANSI COLLATE SQL_Latin1_General_CP1_CI_AS ASC;
SELECT sd.UTF16 AS [UTF16-SQL_Latin1_General_CP1_CI_AS]
FROM @SampleData sd
ORDER BY sd.UTF16 COLLATE SQL_Latin1_General_CP1_CI_AS ASC;
结果:
ANSI-Latin1_General_100_CI_AS
-------------------------------------
ab
a-b
aba
a-b-c
ac
UTF16-Latin1_General_100_CI_AS
-------------------------------------
ab
a-b
aba
a-b-c
ac
ANSI-SQL_Latin1_General_CP1_CI_AS
-------------------------------------
a-b
a-b-c
ab
aba
ac
UTF16-SQL_Latin1_General_CP1_CI_AS
-------------------------------------
ab
a-b
aba
a-b-c
ac
嗯。只有 SQL_ 排序规则与 VARCHAR 字段组合似乎正在执行可以被视为“字符串排序”的操作。 SQL_ 排序规则与NVARCHAR 字段组合将执行“单词排序”,这是与非SQL_ 排序规则相同的Unicode 处理。但是除了确定“字符串”与“单词”排序的 SQL Server 排序规则(即以 SQL_ 开头)之外,还有其他东西吗?让我们看看我们可以提取的排序规则的唯一属性:
SELECT N'Latin1_General_100_CI_AS' AS [CollationName],
COLLATIONPROPERTY('Latin1_General_100_CI_AS', 'CodePage') AS [CodePage],
COLLATIONPROPERTY('Latin1_General_100_CI_AS', 'LCID') AS [LCID],
COLLATIONPROPERTY('Latin1_General_100_CI_AS', 'ComparisonStyle') AS [ComparisonStyle]
UNION ALL
SELECT N'SQL_Latin1_General_CP1_CI_AS' AS [CollationName],
COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'CodePage'),
COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'LCID'),
COLLATIONPROPERTY('SQL_Latin1_General_CP1_CI_AS', 'ComparisonStyle');
结果:
CollationName CodePage LCID ComparisonStyle
---------------------------- -------- ---- ---------------
Latin1_General_100_CI_AS 1252 1033 196609
SQL_Latin1_General_CP1_CI_AS 1252 1033 196609
因此,那里没有明显的差异。这似乎给我们留下了这个:
字符串排序在以下情况下完成:
- 排序规则名称以
SQL_ 开头,AND
- 数据(字段、变量、字符串文字)是非 Unicode(即 CHAR / VARCHAR / TEXT)
有关一般 Unicode 排序的更多信息,请查看以下资源: