https://stackoverflow.com/a/361059/14731讨论了“单词排序”和“字符串排序”之间的区别。
当SQL排序规则使用“单词排序”与“字符串排序”时,如何以编程方式进行查询?
推论:对于Unicode字符串,所有归类都使用“word sort”,对非Unicode字符串使用“string sort”吗?
SELECT * from sys.fn_HelpCollations()
WHERE name = 'SQL_Latin1_General_CP1_CI_AS'
提供了很多关于整理的细节,但请注意它没有提到“单词排序”。
答案 0 :(得分:2)
让我们从Microsoft给出的这些类型的定义开始(取自CompareOptions Enumeration MSDN页面的“备注”部分):
.NET Framework使用三种不同的排序方式:单词排序,字符串排序和顺序排序。单词排序执行文化敏感的字符串比较。某些非字母数字字符可能会分配特殊权重。例如,连字符(“ - ”)可能具有非常小的权重,因此“coop”和“co-op”在排序列表中彼此相邻。字符串排序类似于单词排序,除了没有特殊情况。因此,所有非字母数字符号都在所有字母数字字符之前。序数排序根据字符串中每个元素的Unicode值比较字符串。
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_
,AND 有关Unicode排序的更多信息,请查看以下资源:
答案 1 :(得分:1)
SQL_
整理器处理的非Unicode类型外,所有其他数据都按照“Unicode排序规则”进行排序。根据https://support.microsoft.com/en-us/kb/322112
SQL Server 2000支持两种类型的排序规则:
- SQL排序规则
- Windows排序规则
[...]
对于Windows排序规则,使用与Unicode数据相同的算法来实现非Unicode数据的比较。
[...]
SQL排序规则用于排序非Unicode数据的规则与Microsoft Windows操作系统提供的任何排序例程不兼容;但是,Unicode数据的排序与特定版本的Windows排序规则兼容。
我将此解释为:
SQL_
整理者是“SQL排序规则”SQL_
整理器处理的非Unicode类型外,所有其他数据均按“Windows排序规则”排序。所以,让我们深入研究“Windows排序规则”。
对于Unicode数据类型,数据比较基于Unicode代码点。
// Sorting Flags.
//
// WORD Sort: culturally correct sort
// hyphen and apostrophe are special cased
// example: “coop” and “co-op” will sort together in a list
//
// co_op <——- underscore (symbol)
// coat
// comb
// coop
// co-op <——- hyphen (punctuation)
// cork
// went
// were
// we’re <——- apostrophe (punctuation)
//
//
// STRING Sort: hyphen and apostrophe will sort with all other symbols
//
// co-op <——- hyphen (punctuation)
// co_op <——- underscore (symbol)
// coat
// comb
// coop
// cork
// we’re <——- apostrophe (punctuation)
// went
// were
[...]除了连字符和撇号之外,所有标点符号和其他非字母数字字符都在任何字母数字字符之前。连字符和撇号与其他非字母数字字符的处理方式不同,以确保“coop”和“co-op”等单词在排序列表中保持一致。