繁体   English   中英

在SQL Server更新语句中使用相关子查询会产生意外结果

[英]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列,如其他人所建议的那样。

SQL将使用ID不等于0的记录数来更新每一行。由于所有行ID均等于0,因此不存在不等于0的行,因此不会更新任何内容。

尝试在这里查看此答案:

向现有列添加身份

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM