我正在查询一个带有字符串的 INT
列,如下所示:
SELECT id
FROM (`navigation_links`)
WHERE `navigation_links`.`navigation_link_id` = 'anyRandomString'
(本来,这是偶然的)
- 预期结果:
0
,因为navigation_link_id
是一个INT
- 实际结果:似乎返回了 value 为
0
的每一行
这将返回精确的倒数:
SELECT id
FROM (`navigation_links`)
WHERE `navigation_links`.`navigation_link_id` != 'anyRandomString'
这是精简后的表格:
CREATE TABLE `navigation_links` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`navigation_link_id` INT(10) UNSIGNED NULL DEFAULT '0',
`navigation_group_id` INT(10) UNSIGNED NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
知道这是怎么回事吗?
最佳答案
当比较不同类型的值时,MySQL 会尝试 convert值之一,因此可以进行比较。在字符串和数字的情况下,MySQL 将通过将任何前导数字解释为数字来转换字符串。没有前导数字对应于数值 0,这在几个方面是有意义的:
- 通常可以去掉前导零; '042' 与 '42' 相同。因此“0”和“”是相同的。
将数字字符串转换为数字时,数字的初始值为 0。迭代字符串,将数字与数字相加并乘以基数:
n = 0 while str[i] is a digit character: n += str[i] as a digit ++i return n
如果没有数字字符,则值为0。
空字符串什么都不是,所以字符串开头没有数字的数字字符串什么也不是。在这种思维方式下,
NULL
也可以是没有前导数字的字符串的值,被解释为数字。 MySQL 开发人员并未选择后一个选项,可能是为了使实现稍微简单一些。
关于MySQL 意外返回 "WHERE integer_column = ' string_value' 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8306550/