首页 > 数据库 > > 12.2 在表达式评估的类型转换
参考官方文档:
https://dev.mysql.com/doc/refman/5.7/en/type-conversion.html
当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。 一些转换隐式发生。 例如,MySQL会根据需要自动将数字转换为字符串,反之亦然。
mysql> SELECT 1+'1';
-> 2
mysql> SELECT CONCAT(2,' test');
-> '2 test'
也可以使用CAST()函数明确地将数字转换为字符串。 转换发生在CONCAT()函数中,因为它需要字符串参数。
mysql> SELECT 38.8, CAST(38.8 AS CHAR);
-> 38.8, '38.8'
mysql> SELECT 38.8, CONCAT(38.8);
-> 38.8, '38.8'
以下规则描述了比较操作的转换方式:
一个或多个表中的单行子查询不被视为常量。 例如,如果子查询返回要与DATETIME值进行比较的整数,则比较将作为两个整数完成。 整数不会转换为时间值。 要将操作数作为DATETIME值进行比较,请使用CAST()将子查询值显式转换为DATETIME。
JSON值的比较发生在两个层次上。 第一级比较基于比较值的JSON类型。 如果类型不同,则比较结果仅由哪种类型具有较高的优先级来确定。 如果这两个值具有相同的JSON类型,则会使用特定于类型的规则进行第二级比较。 为了比较JSON和非JSON值,将非JSON值转换为JSON,并将值作为JSON值进行比较。
以下示例说明了将字符串转换为比较操作的数字:
mysql> SELECT 1 > '6x';
-> 0
mysql> SELECT 7 > '6x';
-> 1
mysql> SELECT 0 > 'x6';
-> 0
mysql> SELECT 0 = 'x6';
-> 1
为了将字符串列与数字进行比较,MySQL无法使用列上的索引来快速查找该值。 如果str_col是索引字符串列,则在下列语句中执行查找时,不能使用索引:
SELECT * FROM tbl_name WHERE str_col=1;
原因是有许多不同的字符串可能会转换为值1,如'1',' 1'或'1a'。
使用浮点数(或转换为浮点数的值)的比较是近似的,因为这些数字不准确。 这可能会导致看起来不一致的结果:
mysql> SELECT '18015376320243458' = 18015376320243458; -> 1 mysql> SELECT '18015376320243459' = 18015376320243459; -> 0
这样的结果可能会发生,因为这些值被转换为浮点数,浮点数只有53位的精度,并受四舍五入:
mysql> SELECT '18015376320243459'+0.0; -> 1.8015376320243e+16
此外,从字符串到浮点的转换以及从整数到浮点的转换不一定以相同的方式发生。 CPU可以将整数转换为浮点数,而字符串则在涉及浮点乘法的操作中逐位转换。
所显示的结果在不同的系统上会有所不同,并可能受到诸如计算机体系结构或编译器版本或优化级别等因素的影响。 避免这种问题的一种方法是使用CAST(),以便值不会隐式转换为浮点数:
mysql> SELECT CAST('18015376320243459' AS UNSIGNED) = 18015376320243459;
-> 1
该服务器包括dtoa,一个转换库,为改进字符串或DECIMAL值与近似值(FLOAT / DOUBLE)数字之间的转换提供了基础:
由于该库生成的转换在某些情况下与非dtoa结果不同,因此依赖于先前结果的应用程序中存在不兼容的可能性。 例如,依赖于以前转换的特定准确结果的应用程序可能需要进行调整以适应更高的精度。
dtoa库提供具有以下属性的转换。 D代表具有DECIMAL或字符串表示的值,F代表原生二进制(IEEE)格式的浮点数。
这些性质意味着F→D→F转换是无损的,除非F是-inf,+ inf或NaN。 后面的值不被支持,因为SQL标准将它们定义为FLOAT或DOUBLE的无效值。
对于D→F→D的转换,无损的充分条件是D使用15位或更少位数的精度,不是非规格值-inf,+ inf或NaN。 在某些情况下,即使D的精度超过15位,转换也是无损的,但情况并非总是如此。
将数值或时间值隐式转换为字符串会生成一个值,该值具有由character_set_connection和collation_connection系统变量确定的字符集和排序规则。 (这些变量通常使用SET NAMES设置。)
这意味着除非连接字符集设置为二进制,否则这种转换会生成字符(非二进制)字符串(CHAR,VARCHAR或LONGTEXT值)。 在这种情况下,转换结果是一个二进制字符串(BINARY,VARBINARY或LONGBLOB值)。
对于整数表达式,前面有关表达式的评估对于表达式分配的应用有所不同; 例如,在诸如此类的语句中:
CREATE TABLE t SELECT integer_expr;
在这种情况下,根据整数表达式的长度,由表达式生成的列中的表具有INT或BIGINT类型。 如果表达式的最大长度不适合INT,则使用BIGINT。 该长度取自SELECT结果集元数据的max_length值(请参见第27.8.5节“C API数据结构”)。 这意味着您可以通过使用足够长的表达式来强制使用BIGINT而不是INT:
CREATE TABLE t SELECT 000000000000000000000;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3139279/ ,如需转载,请注明出处,否则将追究法律责任。