为什么sql update on join会更新每个条目,但select会选择正确的条目

yv5phkfx  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(418)

我正在尝试基于另一个表更新一个表。下面的sql更新 myTableA 我本以为它会在哪里更新的 myTableB.active = true :

UPDATE
    myTableA
  SET
    myTableA.enabled = false
  FROM
    myTableA MTA
  FULL OUTER JOIN
    myTableB MTB
  ON
    MTA.user_id = MTB.user_id
  WHERE
    MTB.active = true

上面的代码在mta中更新1000个条目,而不管 MTB.active . 但是,如果将前4行替换为 SELECT * ,则只选择500行,如预期的那样。
我怎样才能只更新 MTA 哪里 MTB.active = true ?

iyzzxitl

iyzzxitl1#

编写此查询的正确方法是:

UPDATE myTableA MTA
  SET myTableA.enabled = false
  FROM myTableB MTB
  WHERE MTA.user_id = MTB.user_id AND MTB.active = true;

引用 myTableAUPDATE 以及 FROM 是不同的参考文献。因此,您的查询正在执行 CROSS JOIN . 在一个 SELECT ,相当于:

FROM MyTableA update_A CROSS JOIN
     (myTableA MTA FULL JOIN
      myTableB MTB
      ON MTA.user_id = MTB.user_id
     )
    WHERE MTB.active = true

显然,过滤器与正在更新的表无关。
还有两点。首先,不太可能 FULL JOIN 会被用在 UPDATE . 通常,行需要匹配才能进行任何更新。此外,还有 = true 是多余的。 active 显然是一个布尔列,因此可以将其用作完整的布尔表达式。

tp5buhyn

tp5buhyn2#

在这里,相关子查询可能已经足够好了:

update mytableA
set enabled = false
where exists (
    select 1
    from mytableB mtb
    where mtb.user_id = mytableA.user_id and mtb.active = true
)
ergxz8rk

ergxz8rk3#

您的查询应如下所示:

UPDATE myTableA MTA
  SET myTableA.enabled = false
  FROM myTableB MTB
  WHERE MTA.user_id = MTB.user_id AND MTB.active = true

相关问题