我真的很困惑。运行以下查询:
SELECT * FROM `articles` WHERE `form` = 'Depotplåster' AND `size` = 5
返回也以“5”开头的行,尽管我既不使用LIKE
也不使用%
通配符运算符。怎么样?
size
字段的类型为VARCHAR
。
答案 0 :(得分:11)
这是因为您正在使用数字和varchar数据之间的比较。 MySQL会隐式将您的列转换为double
,从而生成5
。看到这个简单的测试数据:
mysql> select * from test; +-----------------+ | name | +-----------------+ | 5 | | 5 and some crap | +-----------------+ 2 rows in set (0.00 sec)
现在,“好”方式:比较字符串:
mysql> select * from test where name = '5'; +------+ | name | +------+ | 5 | +------+ 1 row in set (0.00 sec)
和“坏”方式:比较整数:
mysql> select * from test where name = 5; +-----------------+ | name | +-----------------+ | 5 | | 5 and some crap | +-----------------+ 2 rows in set, 1 warning (0.05 sec)
- 这是你的理由:
+---------+------+-----------------------------------------------------+ | Level | Code | Message | +---------+------+-----------------------------------------------------+ | Warning | 1292 | Truncated incorrect DOUBLE value: '5 and some crap' | +---------+------+-----------------------------------------------------+ 1 row in set (0.00 sec)
最后,要明白,为什么会如此:
SELECT
CAST('5' AS DECIMAL) AS 5d,
CAST('5 and some crap' AS DECIMAL) AS 5sd,
CAST('5' AS DECIMAL) = CAST('5 and some crap' AS DECIMAL) AS areEqual;
将导致:
+----+-----+----------+ | 5d | 5sd | areEqual | +----+-----+----------+ | 5 | 5 | 1 | +----+-----+----------+ 1 row in set (0.00 sec)
- 你可以看到,非重要部分被截断(如上面的警告信息中所述)
答案 1 :(得分:1)
SELECT * FROM `articles` WHERE `form` = 'Depotplåster' AND `size` = '5'
-- this will compare the string 'size' with the string '5'
SELECT * FROM `articles` WHERE `form` = 'Depotplåster' AND `size` = 5
-- this will convert string 'size' to integer and then compare with the integer 5
将字符串转换为整数在字符串的开头查找整数,并取最大整数,直到第一个非数字字符。
select '5s4'=5, 's5'=5, '5'=5 -- =>1,0,1
答案 2 :(得分:0)
SELECT *
FROM `articles`
WHERE `form` = 'Depotplåster'
AND `size` = '5'
你应该引用5,因为MySQL将表中的字符串转换为int而没有引号。