MySQL返回不符合搜索条件的多行

时间:2019-06-06 17:36:40

标签: mysql casting floating-point comparison precision

我在本地安装了MySQL,运行SELECT VERSION()返回此值:5.6.43-84.3

当我运行查询时,它仅返回1行时将返回多行。让我进行设置,用这种方式更容易解释。

  1. 创建测试表: CREATE TABLE test_table ( test_val VARCHAR(255) ) ;
  2. 将3个值加载到表中: INSERT INTO test_table (test_val) VALUES ('9671986020630615'), ('9671986020630616'), ('9671986020630617') ;
  3. 运行此查询(该查询返回预期的1行): SELECT * FROM test_table WHERE test_val = '9671986020630615' ;

  4. 运行此查询(此查询返回3行,不应返回): SELECT * FROM test_table WHERE test_val = 9671986020630615 ;

这是我对这种情况的观察:

  1. 第一个查询用双引号将WHERE子句中的值引起来。
  2. 第二个查询不会用单个标记括住WHERE子句中的值。
  3. 测试表中的列定义为VARCHAR(255)
  4. 第一个查询仅返回一行是有意义的,因为它会将WHERE子句中的字符串与测试表(VARCHAR(255))中的字符串值进行比较
  5. 当MySQL将第二个查询的WHERE子句中的数值与测试表(VARCHAR(255))中的字符串值进行比较时,发生了某些事情,这导致MySQL返回3行,而不仅仅是返回1。

第一个查询返回正确的结果是有意义的,因为它正在将字符串与字符串进行比较。

从某种意义上说,第二个查询正在返回错误的数据集(3行,而不是应返回的1行)。

但是我的问题是为什么这样做吗?为什么当将VARCHAR(255)子句中的数值的真值仅匹配1行时,将一个数字与3个不同的WHERE值进行比较时,它会返回所有3行?

因此,从本质上讲,第一个查询是MySQL在说:

  

'9671986020630615'='9671986020630615'

     

'9671986020630615'<>'9671986020630616',

     

'9671986020630615'<>'9671986020630617'

但是对于第二个查询,它说:

  

9671986020630615 ='9671986020630615',

     

9671986020630615 ='9671986020630616',

     

9671986020630615 ='9671986020630617'

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:5)

MySQL使用IEEE double-precision floating point representation,以与JavaScript相同的方式在内部处理所有数字。

当您省略长数字字符串中的引号时,即您用Float32Array代替9671986020630615时,MySQL使用该数字。然后,当它运行查询的'9671986020630615 '部分时,它会默默地将每个列值强制为双精度数字。

但是由于双精度machine epsilon -- the limit of precision,所以9671986020630615、9671986020630616和9671986020630617都具有相同的值。因此,WHERE会找到所有这三个。

WHERE

看看所有三个整数如何具有与DOUBLE相同的表示形式?