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

Gha*_*eak 4 mysql floating-point precision comparison casting

我在本地安装了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 * FROMtest_table WHEREtest_val= '9671986020630615' ;

  4. 运行此查询(此查询返回3行,不应返回): SELECT * FROMtest_table WHEREtest_val= 9671986020630615 ;

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

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

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

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

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

因此,实质上,对于第一个查询,MySQL就是这样说的:

'9671986020630615'='9671986020630615',

'9671986020630615'<>'9671986020630616',

'9671986020630615'<>'9671986020630617'

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

9671986020630615 ='9671986020630615',

9671986020630615 ='9671986020630616',

9671986020630615 ='9671986020630617'

任何帮助都感激不尽。

O. *_*nes 5

MySQL使用IEEE双精度浮点表示法,内部处理所有数字的方式与Javascript相同。

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

但是由于机器epsilon(精度极限)的双重精度,9671986020630615、9671986020630616和9671986020630617都具有相同的值。因此,WHERE会找到所有这三个。

CAST(9671986020630615 AS DOUBLE) CAST(9671986020630616 AS DOUBLE) CAST(9671986020630617 AS DOUBLE) 
     9.671986020630616e15             9.671986020630616e15             9.671986020630616e15 | 
Run Code Online (Sandbox Code Playgroud)

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