UPDATE 查询更改了没有 WHERE 子句但有 AND 子句的行 - 为啥?
Posted
技术标签:
【中文标题】UPDATE 查询更改了没有 WHERE 子句但有 AND 子句的行 - 为啥?【英文标题】:UPDATE query changed rows without a WHERE clause but had an AND clause - why?UPDATE 查询更改了没有 WHERE 子句但有 AND 子句的行 - 为什么? 【发布时间】:2011-08-31 16:12:32 【问题描述】:我运行了以下查询,它应该有一个 where 子句,但我忘了添加它:
UPDATE
tblFormElementInstances as fei
JOIN
tblFormElements as fe using(intFormElementId)
SET
fei.intStep = 1
AND
fei.intDivisionId = 1 OR fei.intDivisionId IS NULL);
mysql 返回以下消息:
--查询正常,影响 42 行(0.06 秒) --匹配行:94 更改:42 警告:0
我原以为它会引发语法错误,但事实并非如此。此外,该表中有 96 行,具有不同的 intDivisionIds(即不仅仅是 1 或 NULL),这表明 MySQL 完成了一些过滤(匹配的行数 = 94)。
另外,intStep 实际上改为 0,而不是 1。
有谁知道:
1) 为什么这个查询有效? 2) 为什么将 intStep 更改为 0 而不是 1? 3) 为什么不匹配所有 96?
(更改为 42 的计数是因为某些行已经有 intStep = 1。)
【问题讨论】:
这里必须有语法错误,因为右括号不匹配。 是的,抱歉,AND 后面有一个括号,我在粘贴查询时必须删除它。 【参考方案1】:它没有语法错误,因为1 AND <expr>
是一个有效的表达式。
您将 intStep 设置为该表达式(我已添加括号以显示优先级):
SET intStep = ((1 AND (fei.intDivisionId = 1)) OR (fei.intDivisionId IS NULL))
这是一个布尔表达式,为 0 或 1,因此它将某些行更改为 0,将某些行更改为 1。如果 intDivisionId 不为 1,并且如果 intDivisionId 不为 null,则更改为 0。
我猜你在 tblFormElementInstances 中有 96 行,但这些行中只有 94 行在 tblFormElements 中有匹配的行。 JOIN 意味着只有匹配的行才有资格进行 UPDATE。
试试这个查询来测试这个理论,我敢打赌它会返回 94:
SELECT COUNT(*) FROM tblFormElementInstances as fei
JOIN tblFormElements as fe using(intFormElementId)
@Jason McCreary 很好地观察到您的示例末尾有一个不平衡的括号。这应该会导致语法错误。由于您说您没有收到语法错误,因此我认为括号是错误地包含在您的示例中。
【讨论】:
太棒了,谢谢你完美的回答!你是对的,选择查询返回 94。【参考方案2】:-
不确定。我同意尾随的单独
)
应该导致语法错误。也许 MySQL 没有那么严格。
因为1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL
的结果是0
。正如您自己指出的那样,第一个 AND
应该是 WHERE
您的 JOIN
很可能与 other 表中的 2 行不匹配。
【讨论】:
1 - 我在 AND 之后错过了一个开头的括号,怀疑 MySQL 是否松懈 :)以上是关于UPDATE 查询更改了没有 WHERE 子句但有 AND 子句的行 - 为啥?的主要内容,如果未能解决你的问题,请参考以下文章
UPDATE 查询的 WHERE 子句中的 SELECT 查询 [重复]
sql中的update操作时 如果没有用到where子句会怎么样?
WHERE 子句中带有子查询的 MYSQL UPDATE 查询 - 优化