使用一对多连接的 SQL 更新行为

Ant*_*nty 5 sql ms-access sql-update

假设我有两个表,t1t2t1有两个字段,一个包含名为a的唯一值,另一个包含名为value的字段。表t2有一个不包含唯一值的字段称为b)和一个也称为value 的字段。现在,如果我使用以下更新查询(顺便说一句,这是使用 MS Access):

UPDATE t1
INNER JOIN t2 ON t1.a=t2.b
SET t1.value=t2.value
Run Code Online (Sandbox Code Playgroud)

如果我有以下数据

     t1                  t2
 a  | value          b  | value
------------        ------------
'm' |  0.0           'm'|  1.1
                     'm'|  0.2
Run Code Online (Sandbox Code Playgroud)

并运行查询 t1.value 最终得到什么值?我运行了一些测试,但找不到一致的行为,所以我猜测它可能只是未定义。或者这种更新查询是不应该做的?关于为什么我必须这样做,有一个很长的无聊故事,但这与我的询问的技术性质无关。

Gar*_*thD 5

这称为非确定性查询,这正是您所发现的,您可以多次运行查询而不更改查询或基础数据并获得不同的结果。

实际上,发生的情况是该值将使用遇到的最后一条记录进行更新,因此在您的情况下它将更新两次,但第一次更新将被最后一次覆盖。你完全无法控制的是 SQL 引擎访问记录的顺序,它将按照它认为合适的顺序访问它们,这可能只是从一开始的聚集索引扫描,或者它可以使用其他索引并访问不同顺序的聚集索引。你没有办法知道这一点。多次运行更新很可能会产生相同的结果,因为在不更改数据的情况下,sql 优化器将使用相同的查询计划。但同样没有保证,因此您不应依赖非确定性查询来获取确定性结果。


编辑

要将 T1 中的值更新为 T2 中的最大对应值,您可以使用DMax

UPDATE  T1
SET     Value = DMax("Value", "T2", "b=" & T1.a);
Run Code Online (Sandbox Code Playgroud)