Implicit conversion of a numeric in mysql

不打扰是莪最后的温柔 提交于 2021-02-04 21:51:01

问题


table struct:

CREATE TABLE `test_table` (
  `pk_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL,
  `password` varchar(128) NOT NULL,
  `version` bigint(20) NOT NULL,
  PRIMARY KEY (`pk_id`)
) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551601 DEFAULT CHARSET=utf8;

data:

/*
-- Query: SELECT * FROM test_table
-- Date: 2017-09-15 16:51
*/
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (10545342555594296735,'testabc','testabc',5);
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (10545342555594297155,'testdef','testdef',0);
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (10545342555594298139,'testghi','testghi',0);
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (18446744073709551601,'testjkl','testjkl',0);
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (18446744073709551602,'testmno','testmno',0);
INSERT INTO `test_table` (`pk_id`,`name`,`password`,`version`) VALUES (18446744073709551603,'testpqr','testpqr',0);

run sql:

SELECT 
    *
FROM
    test_table
WHERE
    CAST(pk_id AS CHAR) = 18446744073709551601;

result:

# pk_id, name, password, version
'18446744073709551601', 'testjkl', 'testjkl', '0'
'18446744073709551602', 'testmno', 'testmno', '0'
'18446744073709551603', 'testpqr', 'testpqr', '0'

I am confused about implicit conversion,What happened?I've checked out the official website about implicit conversion rules.But I still don't understand.Someone can help me.


回答1:


You could check this link for more information about type conversion.

The following rules describe how conversion occurs for comparison operations:

1 - If one or both arguments are NULL, the result of the comparison is NULL, except for the NULL-safe <=> equality comparison operator. For NULL <=> NULL, the result is true. No conversion is needed.

2 - If both arguments in a comparison operation are strings, they are compared as strings.

3 - If both arguments are integers, they are compared as integers.

4 - Hexadecimal values are treated as binary strings if not compared to a number.

5 - If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to IN()! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using BETWEEN with date or time values, use CAST() to explicitly convert the values to the desired data type.

6 - A single-row subquery from a table or tables is not considered a constant. For example, if a subquery returns an integer to be compared to a DATETIME value, the comparison is done as two integers. The integer is not converted to a temporal value. To compare the operands as DATETIME values, use CAST() to explicitly convert the subquery value to DATETIME.

7 - If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.

8 - In all other cases, the arguments are compared as floating-point (real) numbers.

In your case, the arguments are compared as floating-point (real) numbers. Comparisons that use floating-point numbers (or values that are converted to floating-point numbers) are approximate because such numbers are inexact. This might lead to results that appear inconsistent.

You could check below query will generate same result for VALUE1, VALUE2, VALUE3 and VALUE4. That why your query's returned such that result.

SELECT 
    '18446744073709551601' + 0E0 AS VALUE1,
    '18446744073709551602' + 0E0 AS VALUE2,
    '18446744073709551603' + 0E0 AS VALUE3,
     18446744073709551601 + 0E0 AS VALUE4

If you want the query behaves as expected, you should change both arguments to string

CAST(pk_id AS CHAR) = '18446744073709551601';


来源:https://stackoverflow.com/questions/46235729/implicit-conversion-of-a-numeric-in-mysql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!