有人可以用该查询解释我的原因:
SELECT * FROM `tags` WHERE (tag IN ('willa-lentza', 2016))
它会从tags
表中返回所有行,但是当我将2016
放入引号时它的效果很好吗?
tag
列为varchar
类型。
样本环境
CREATE TABLE `tags` (
`id` int(10) unsigned NOT NULL auto_increment,
`tag` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
INSERT INTO `tags` (`id`, `tag`) VALUES
(1, '2016'),
(2, 'plum'),
(3, 'banana'),
(4, 'apple'),
(5, 'willa-lentza');
我也得到了与Roland Bouman相同的错误:
Truncated incorrect DOUBLE value: 'willa-lentza'
答案 0 :(得分:4)
你永远不应该混合引用和 IN列表中的未加引号的值,因为 引用值的比较规则 (例如字符串)和不带引号的值 (如数字)不同。混合类型 因此可能导致不一致 结果
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_in
答案 1 :(得分:1)
有趣......我得到了这个。
mysql> select 'a' in (0, 'b');
+-----------------+
| 'a' in (0, 'b') |
+-----------------+
| 1 |
+-----------------+
1 row in set, 1 warning (0.00 sec)
Warning (Code 1292): Truncated incorrect DOUBLE value: 'a'
编辑:实际上我认为我可以推翻这一个。 (因为0在列表中,mysql认为其余的og在列表中,左手参数'a'应该都是数字。铸造'a'将导致0,所以这将被视为{{1 }}
但我还是无法解释OP的行为
答案 2 :(得分:0)
我的简短测试并未证实此行为。
SELECT 'test' IN ('other-string', 2016) /* returns 0 */
不只是任何字符串都应该能够匹配整数。你确定你没有改变其他任何东西吗?
答案 3 :(得分:0)
我无法重现此行为,但似乎您的varchars
会被投放到DOUBLEs
而不是相反。
在这种情况下,查询变为:
SELECT *
FROM tags
WHERE CAST(tag AS DOUBLE) /* =0 for non-numeric tags */ IN (CAST('willa-lentza AS DOUBLE) /* = 0 */, 2016)
对于所有非数字标签始终为true。
您可以在此声明中运行EXPLAIN EXTENDED SELECT ...
并在此处发布警告吗?
要确认此行为,您可以添加其他数字标记:
INSERT
INTO tags
VALUES (6, '1000')
这两个查询都不应该返回此标记。
为避免这种情况,只需将常量括在单引号中,以便将它们解析为CHARs