https://stackoverflow.com/a/361059/14731讨论“单词排序”和“字符串排序”之间的区别。
当 SQL 排序规则使用“单词排序”与“字符串排序”时,如何以编程方式进行查询?
推论:是否所有排序规则都对 Unicode 字符串使用“单词排序”,对非 Unicode 字符串使用“字符串排序”?
SELECT * from sys.fn_HelpCollations()
WHERE name = 'SQL_Latin1_General_CP1_CI_AS'
提供了有关排序规则的大量详细信息,但请注意,它没有提及“单词排序”。
最佳答案
让我们从 Microsoft 给出的这些类型的定义开始(取自 CompareOptions Enumeration MSDN 页面的“备注”部分):
The .NET Framework uses three distinct ways of sorting: word sort, string sort, and ordinal sort. Word sort performs a culture-sensitive comparison of strings. Certain nonalphanumeric characters might have special weights assigned to them. For example, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list. String sort is similar to word sort, except that there are no special cases. Therefore, all nonalphanumeric symbols come before all alphanumeric characters. Ordinal sort compares strings based on the Unicode values of each element of the string.
Unicode 是文化敏感且加权的,并且 XML
和 N
前缀类型是 Unicode,因此他们可以说 Unicode 类型中的数据使用“字排序” "而非 Unicode 类型的数据则使用“字符串排序”。序数指的是 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_
开头,并且 - 数据(字段、变量、字符串文字)是非 Unicode(即 CHAR/VARCHAR/TEXT)
有关 Unicode 排序的更多信息,请查看以下资源:
- Unicode Collation Charts (per language) - 显示每种语言的字符,显示它们的排序方式
- Unicode Collation Algorithm (UCA) - 对用于对 Unicode 数据进行排序的算法进行一些“简单”(哈!)阅读 - 这是有效的默认算法,除非被特定区域设置的规则覆盖。
- Collation Guidelines - 如何阅读特定于语言环境的覆盖图表
关于sql-server - 如何判断排序规则是使用单词排序还是字符串排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32209137/