I’m querying an INT column with a string, like this:
SELECT id
FROM (`navigation_links`)
WHERE `navigation_links`.`navigation_link_id` = 'anyRandomString'
(originally, this was by accident)
- Expected results:
0, becausenavigation_link_idis anINT - Actual results: It seems to return every row whose value is
0
This returns the exact inverse:
SELECT id
FROM (`navigation_links`)
WHERE `navigation_links`.`navigation_link_id` != 'anyRandomString'
Here is the table, stripped down:
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`)
)
Any idea what this is all about?
When comparing values of different types, MySQL will attempt to convert one of the values so comparison is possible. In the case of strings and numbers, MySQL will convert the string by interpreting any leading digits as a number. No leading digits corresponds to a numeric value of 0, which makes sense in a couple of ways:
When converting a numeric string to a number, the initial value for the number is 0. The string is iterated over, adding the digits to the number and multiplying by the base:
If there are no digit characters, the value is 0.
An empty string is nothing, so the numeric string at the beginning of a string that starts with no digits is nothing. Under this way of thinking,
NULLcould also be the value for a string with no leading digits interpreted as a number. This latter option was not picked by the MySQL developers, possibly to make implementation slightly simpler.