UPDATE查询更改了行而没有WHERE子句但是有一个AND子句 - 为什么?

时间:2011-08-31 16:12:32

标签: mysql where

我运行了以下查询,该查询应该有一个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返回以下消息:

- 查询OK,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。)

2 个答案:

答案 0 :(得分:4)

它没有语法错误,因为1 AND <expr>是一个有效的表达式。

将intStep设置为此表达式(我添加了括号以显示优先级):

SET intStep = ((1 AND (fei.intDivisionId = 1)) OR (fei.intDivisionId IS NULL))

这是一个布尔表达式,它是0或1,因此它将某些行更改为0,将某些行更改为1.如果intDivisionId不是1,则更改为0,如果intDivisionId不为null。

我猜你在tblFormElementInstances中有96行,但这些行中只有94行在tblFormElements中有匹配的行。 JOIN表示只有匹配的行才有资格获得UPDATE。

尝试此查询来测试这个理论,我打赌它会返回94:

SELECT COUNT(*) FROM tblFormElementInstances as fei
JOIN tblFormElements as fe using(intFormElementId)

@Jason McCreary很好地观察到你的例子末尾有一个不平衡的括号。这应该会导致语法错误。既然你说你没有得到语法错误,我认为你的例子中错误地包含了括号。

答案 1 :(得分:1)

  1. 不确定。我同意结尾,单独的)应该导致语法错误。也许MySQL并不那么严格。
  2. 因为1 AND fei.intDivisionId = 1 OR fei.intDivisionId IS NULL的结果是0。正如您所指出的那样,首先AND应该是WHERE
  3. 您的JOIN很可能与其他表中的2行不匹配。