我正在尝试基于另一个表更新一个表。以下SQL在我期望它更新myTableB.active = true
的位置时更新myTableA
中的每个条目:
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
中的条目?
编写此查询的正确方法是:
UPDATE myTableA MTA
SET myTableA.enabled = false
FROM myTableB MTB
WHERE MTA.user_id = MTB.user_id AND MTB.active = true;
UPDATE
和FROM
中对myTableA
的引用是不同的引用。 因此,您的查询正在执行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
显然是一个布尔列,因此它可以用作完整的布尔表达式。
一个相关的子查询在这里可能就足够了:
update mytableA
set enabled = false
where exists (
select 1
from mytableB mtb
where mtb.user_id = mytableA.user_id and mtb.active = true
)
您的查询应如下所示:
UPDATE myTableA MTA
SET myTableA.enabled = false
FROM myTableB MTB
WHERE MTA.user_id = MTB.user_id AND MTB.active = true