[英]Using correlated subquery in SQL Server update statement gives unexpected result
我正在将主键列引入还没有的表。 添加默认值为0的普通字段Id
(int)之后,我尝试使用以下更新语句为每个记录创建唯一值:
update t1
set t1.id = (select count(*) from mytable t2 where t2.id <> t1.id)
from mytable t1
我希望为每行执行子查询,因为我引用的是t1
。 每次执行子查询时,计数应减少一,但不起作用。
结果是,每个记录中的Id仍为0。 我曾经在其他DBMS上成功使用过此功能。 我在这里使用SQL Server 2008。
如何为每个记录生成唯一值并更新ID字段?
试图解释为什么它不能按您期望的那样工作 :
我希望对每行执行子查询,因为我引用的是t1。
它被执行,并且可能影响所有行。 但是UPDATE
语句是一条语句,它作为一条语句执行,该语句会影响整个表(如果有WHERE
子句,则影响部分表)。
每次执行子查询时,计数应减少一,但不起作用。
您期望执行UPDATE
每行对子查询进行一次评估。 但是,首先评估一个语句-针对所有受影响的行-然后更改(更新)行。 (DBMS可能会这样做,但是结果应该仍然像这样做一样)。
结果是,每个记录中的Id仍为0。
当所有行在执行前具有相同的0
值时,这就是该语句的正确和预期的行为。 COUNT(*)
为0
。
我曾经在其他DBMS上成功使用过此功能。
我的“疯狂”猜测是您已在MySQL中使用它。 (更正/更新:我的猜测是错误的,此更新的语法对MySQL无效,显然查询在Firebird中“正确”运行)。 UPDATE
在该DBMS中无法以标准方式工作。 正如您所了解的那样,它可以逐行而不是与整个表一起工作。
我在这里使用SQL Server 2008。
此DBMS可与UPDATE
正常使用。 您可以编写其他更新语句,该语句将具有所需的结果,或者更好的是,使用自动生成的IDENTITY
列,如其他人所建议的那样。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.