在PostgreSQL中的一个查询中使用不同的主键更新多行?

在PostgreSQL中的一个查询中使用不同的主键更新多行?,sql,postgresql,sql-update,postgresql-9.1,sql-optimization,Sql,Postgresql,Sql Update,Postgresql 9.1,Sql Optimization,在PostgreSQL 9.1中,我必须更新许多行中的许多列。我目前正在处理许多不同的UPDATE查询,每个查询在不同的行上工作(基于主键): 我必须做几千次这样的查询 在PostgreSQL中,我是否可以在一个查询中“批量更新”大量行?如果您使用的是INSERT,您可以一次插入多行:(INSERT-INTO-mytable(column_a,column_b)值((12,6)、(1,45));),是否有类似于更新的内容 比如: UPDATE mytable SET (id, column_a,

在PostgreSQL 9.1中,我必须更新许多行中的许多列。我目前正在处理许多不同的
UPDATE
查询,每个查询在不同的行上工作(基于主键):

我必须做几千次这样的查询

在PostgreSQL中,我是否可以在一个查询中“批量更新”大量行?如果您使用的是
INSERT
,您可以一次插入多行:(
INSERT-INTO-mytable(column_a,column_b)值((12,6)、(1,45));
),是否有类似于
更新的内容

比如:

UPDATE mytable SET (id, column_a, column_b) FROM VALUES ( (1, 12, 6), (2, 1, 45), (3, 56, 3), … )
?


重要的一点是,每个“值”只会更新一行(基于
其中id=
)。每一行都有相同的、固定数量的需要更新的列,但每一行的每一列都有不同的值,因此
updatemytable SET column_a=12,column_b=6,其中id在(1,2,3)中无效。

如果这适用于您的案例,您可以使用它

create table test(id int, a int, b int);

insert into test(id, a, b)
values
(1, 1, 1),
(2, 1, 1),
(3, 1, 1),
(4, 1, 1),
(5, 1, 1),
(6, 1, 1),
(7, 1, 1);


update test as d
set a = s.a, b = s.b
from 
(
  values
  (1, 2, 2),
  (2, 2, 2)
) as s(id, a, b)
where d.id = s.id

是的,您可以(在SQL中通常是首选)一次更新多行。有几种方法可以做到这一点,但我认为最具可读性和优雅性的是使用id和值的派生表:

update mytable as m set
    column_a = c.column_a,
    column_b = c.column_b
from (values
    (1, 12, 6),
    (2, 1, 45),
    (3, 56, 3)
) as c(id, column_a, column_b)
where c.id = m.id
虽然可读性不强,但更明显的解决方案是使用
case

update mytable set
    column_a = case id when 1 then 12 when 2 then 1 when 3 then 56 end,
    column_b = case id when 1 then 6 when 2 then 45 when 3 then 3 end
where id in (1, 2, 3)

这个方法对我来说太棒了!!谢谢还可用于连接多个键/列。也就是说,“其中c.id=m.id,c.column_a=m.column_a”;我得到一个“重复的键值违反了唯一约束”。我有一个复合的唯一索引,我试图一次更新多行以使用它们。
update mytable set
    column_a = case id when 1 then 12 when 2 then 1 when 3 then 56 end,
    column_b = case id when 1 then 6 when 2 then 45 when 3 then 3 end
where id in (1, 2, 3)