postgresql Update语句意外更新表中的所有行

jyztefdp  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(148)

我试图用另一个表的主键(ro_id)覆盖表中的主键(draft_id)。我只想对总数24k中的56行中的一小部分行这样做。
我在两个表中使用单独的行group_id连接表。我还有一个额外的where子句来确保我只更新所需的行。我的查询如下:

update data.foo
set draft_id = ro.ro_id
from data.foo r
         inner join data.bar as ro on r.group_id = ro.group_id
where r.draft_id in
      ('d49aaa45-2dd0-45aa-9e72-131b790fc75c', ...);

字符串
问题是这个查询会更新每一行,而不是预期的56行:

UPDATE 24589


然而,当我运行这个查询时,我得到的计数为56:

select count(r.draft_id)
from data.foo r
         inner join data.bar as ro on r.group_id = ro.group_id
where r.draft_id in
      ('d49aaa45-2dd0-45aa-9e72-131b790fc75c', ...);


我简化了where子句中使用的键列表,但有56个,我相信它们是正确的。
update语句如何更新比where子句中给定的键更多的行?
为了清楚起见,下面是用于创建data.bar表的SQL,其中data.foo有两个相同的列。

CREATE TABLE IF NOT EXISTS data.bar
(
    draft_id UUID NOT NULL
        CONSTRAINT bar_pkey PRIMARY KEY,
    group_id       TEXT
);


我使用以下版本:
psql(12.16,server 13.11(Ubuntu 13.11-1.pgdg22.04 +1))

dgsult0t

dgsult0t1#

您忘记添加WHERE条件,该条件将fooFROM子句连接起来。因此,所有行都将更新。
您的关键错误是该语句使用了两次foo:一次在UPDATE子句中,一次在FROM子句(别名r)中。您的语句连接了三个表:

  • foo
  • foo,别名为r
  • bar,别名为ro

由于没有WHERE条件将foorro连接起来,因此最终得到一个包含foo中所有行的 cross join
但实际上,您只想连接两个表:foobar

UPDATE data.foo
SET draft_id = ro.ro_id
FROM data.bar
WHERE foo.group_id = bar.group_id
  AND foo.draft_id IN ('d49aaa45-2dd0-45aa-9e72-131b790fc75c', ...);

字符串

相关问题