前言
之前一篇文章讲了排序规则的基本概念和误区。今天的文章我主要针对论坛里面一个朋友问他问题,深入的讲下排序规则。这些东西是我感觉我查了很多资料和博客都没有讲到的内容。本文尽量通过自己的理解,使用通俗易懂的语言来讲解。希望能够帮助大家更加深入的了解他的工作原理.
案例
SELECT * FROM (
SELECT '-' AS t
UNION
SELECT '1' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
SELECT * FROM (
SELECT '-11' AS t
UNION
SELECT '11' AS t
) A
ORDER BY A.t
COLLATE Chinese_PRC_CI_AS
执行结果截图如下:
为什么这2个查询结果会是上面的这个结果呢。-和1怎么比较。11为什么比-11还小?看起来这个结果
分析
通过之前的文章我们知道,Chinese_PRC_CI_AS 是我们在中国地区默认的排序规则。表示支持的中国大陆的 不区分大小写,区分重音的字符集。这是我们最常用的排序规则之一。首先上面的案例中,是对字符串进行排序,而不是对应的阿拉伯数字进行排序。那么他需要按照对应的排序规则来对字符串进行排序。Chinese_PRC_CI_AS 使用的是windows排序规则。它对应的代码页是936.
代码页
在之前我也一直很疑惑,什么是代码页,排序规则和代码页有什么关系,和字符集(GBK,UTF8等)又有什么联系和区别。其实,代码页也称为“内码表”,是与特定语言的字符集相对应的一张表。操作系统中不同的语言和区域设置可能使用不同的代码页.代码页和字符集是对应的。但是代码页一般与其所直接对应的字符集之间并非完全等同,往往因为种种原因(比如标准跟不上现实实践的需要)而会对字符集有所扩展。代码页的指定在Windows中是系统默认设置的(即默认系统区域设置),也可在(Windows7的)“控制面板-区域和语言-管理-非Unicode程序的语言-更改系统区域设置”中选择列表中的语言进行更改。
字符集和字符编码
总结
SELECT * FROM (
SELECT '-11' AS t
UNION
SELECT '11' AS t
) A
ORDER BY cast(A.t as int)