sql-server - 如何判断排序规则是使用单词排序还是字符串排序?

标签 sql-server sorting unicode collation

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 是文化敏感且加权的,并且 XMLN 前缀类型是 Unicode,因此他们可以说 Unicode 类型中的数据使用“字排序” "而非 Unicode 类型的数据则使用“字符串排序”。序数指的是 BINBIN2 排序规则,尽管 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 排序的更多信息,请查看以下资源:

关于sql-server - 如何判断排序规则是使用单词排序还是字符串排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32209137/

相关文章:

php - 在这种情况下是 preg_replace 还是 mb_ereg_replace?

c# - 如何使用通配符搜索参数化?

c# - 在应用程序中包含 SQL Server 数据库

sql-server - SQL 按日期范围内的频率进行分组

c - 使用第一个元素作为枢轴的 C 中的快速排序实现

java - 在没有任何 Collection API 的情况下根据 LastName 对二维字符串数组进行排序

ios - 在 Ios 中排序时间范围

sql-server - 在 SQL Server 中有条件地创建用户

python - 如何使用Python从mysql数据库获取并打印utf-8数据?

python - Python 中 unicode 的问题