收集子句优先级
COLLATE子句具有较高的优先级(高于||),因此以下两个表达式是等效的:
x || y COLLATE z
x || (y COLLATE z)
字符集和排序规则兼容性
每个字符集都有一个或多个排序规则,但是每个排序规则都与一个且只有一个字符集相关联。因此,以下语句将导致错误消息,因为latin2_bin排序规则与latin1字符集不合法:
mysql> SELECT _latin1 'x' COLLATE latin2_bin;
ERROR 1253 (42000): COLLATION 'latin2_bin' is not valid
for CHARACTER SET 'latin1'
表达式中的排序规则强制性
在绝大多数语句中,很明显MySQL使用什么排序规则来解决比较操作。例如,在以下情况下,应该清楚排序规则是column的排序规则x:
SELECT x FROM T ORDER BY x;
SELECT x FROM T WHERE x = x;
SELECT DISTINCT x FROM T;
但是,对于多个操作数,可能会有歧义。例如:
SELECT x FROM T WHERE x = 'Y';
比较是否应该使用列x或字符串文字 的排序规则 'Y'?双方x并 'Y'有排序规则,所以其整理的优先级?
排序规则的混合也可能在比较之外的其他情况下发生。例如,多参数串联操作(例如,CONCAT(x,'Y') 组合其参数以产生单个字符串)。结果应该具有什么排序规则?
为了解决这样的问题,MySQL检查是否可以将一项的排序规则强制为另一项的排序规则。MySQL分配强制性值如下:
1、显式COLLATE子句的强制性为0(根本不可强制)。
2、具有不同排序规则的两个字符串的串联的强制性为1。
3、列或存储的例程参数或局部变量的排序规则的强制性为2。
4、“ 系统常数 ”(由功能,例如返回的字符串USER()或 VERSION())具有为3的可压缩性。
5、文字的排序规则的强制性为4。
6、数字或时间值的排序规则的强制性为5。
7、NULL或衍生自的表达式NULL的矫顽力为6。
MySQL使用强制性值和以下规则来解决歧义:
1、使用强制性最低的排序规则。
2、如果双方具有相同的强制性,则:
(1)如果双方都是Unicode,或者双方都不是Unicode,则错误。
(2)如果其中一方具有Unicode字符集,而另一方具有非Unicode字符集,则具有Unicode字符集的一方获胜,并且自动字符集转换将应用于非Unicode一方。例如,以下语句不返回错误:
SELECT CONCAT(utf8_column, latin1_column) FROM t1;
它返回一个结果,该结果的字符集为 utf8,排序规则与相同 utf8_column。的值 latin1_column会utf8在连接前自动转换为。
(3)对于具有来自相同字符集但混合使用_bin归类和a _ci或_cs 归类的操作数的运算,将使用归类_bin。这类似于混合非二进制和二进制字符串的操作如何将操作数评估为二进制字符串,不同之处在于它用于排序规则而不是数据类型。
尽管自动转换不在SQL标准中,但该标准确实指出,每个字符集(就支持的字符而言)都是Unicode 的“ 子集 ”。因为众所周知的原则是“ 适用于超集的内容可以适用于子集 ”,所以我们认为Unicode的排序规则可以适用于与非Unicode字符串的比较。
下表说明了上述规则的一些应用。
比较方式 使用的归类
column1 = 'A' 使用排序规则 column1
column1 = 'A' COLLATE x 使用排序规则 'A' COLLATE x
column1 COLLATE x = 'A' COLLATE y 错误
要确定字符串表达式的可强制性,请使用 COERCIBILITY()函数(请参见 第12.15节“信息函数”):
mysql>SELECT COERCIBILITY('A' COLLATE latin1_swedish_ci);
-> 0
mysql>SELECT COERCIBILITY(VERSION());
-> 3
mysql>SELECT COERCIBILITY('A');
-> 4
mysql>SELECT COERCIBILITY(1000);
-> 5
对于将数值或时间值隐式转换为字符串的情况(例如1在表达式中的参数中发生的情况)CONCAT(1, 'abc'),结果是一个字符(非二进制)字符串,该字符串具有由character_set_connection和 collation_connection变量决定的字符集和排序规则 。