where只指定一行,为什么这个更新会影响两行?

tkclm6bt  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(375)

请对照sakila示例数据库检查我在mysql 8.0中运行的以下更新语句:

UPDATE `film`
SET
    `original_language_id` = FLOOR(1 + (RAND() * 6))
WHERE
    `film_id` = FLOOR(1 + (RAND() * 1000));

其思想是从 film 拥有 original_language_id 该行的列键的值介于1和6之间。
这个 film 表中有1000行,pks从1到1000。这个 original_language_id 列是 language table。这个 language 表中有6行,pks从1到6。
mysql认为上述update语句不安全(错误1175)(我很想知道为什么,但这不是我的问题)。因此,为了迫使语句运行,我在它前面加上: SET SQL_SAFE_UPDATES = 0; .
当我运行update语句时,我希望在output窗口中看到:
1行受影响的行匹配:1更改:1警告:0
但是我有时会受到0行的影响,有时是1行,有时是2行!
我的问题是为什么这个update语句不一致地影响一行并且只影响一行?
ps-请避免评论查询对您是否有意义和/或禁用安全更新模式的谨慎性。这个问题是一个学习目的的练习,我完全意识到上述模式的重要性。谢谢您。

vnjpjtjt

vnjpjtjt1#

这个 WHERE 条款:

WHERE `film_id` = FLOOR(1 + (RAND() * 1000))

对表的每一行执行,每次生成一个新的随机数并对照列的值进行检查 film_id .
所以有时这两个数字相等,可以是1,2,或多行,甚至没有。
如果只想更新1个随机行,可以加入一个返回1个随机数的查询,如下所示:

UPDATE `film` f
INNER JOIN (SELECT FLOOR(1 + (RAND() * 1000)) rnd) t
ON t.rnd = f.`film_id`
SET `original_language_id` = FLOOR(1 + (RAND() * 6))
drkbr07n

drkbr07n2#

如果您想随机选择一行进行更新,那么您可以使用 order by rand() 以及 limit 1 :

update film
set original_language_id = floor(1 + (rand() * 6))
order by rand()
limit 1

这应该比使用联接的其他解决方案更有效—而且不管表中有多少行,它都可以工作(而您最初的方法要求您事先知道表中有多少行)

相关问题