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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18936896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 01:06:59  来源:igfitidea点击:

Updating multiple rows with different primary key in one query in PostgreSQL?

sqlpostgresqlsql-updatepostgresql-9.1sql-optimization

提问by Rory

I have to update many columns in many rows in PostgreSQL 9.1. I'm currently doing it with many different UPDATEqueries, each one that works on a different row (based on the primary key):

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

UPDATE mytable SET column_a = 12, column_b = 6 WHERE id = 1;
UPDATE mytable SET column_a = 1, column_b = 45 WHERE id = 2;
UPDATE mytable SET column_a = 56, column_b = 3 WHERE id = 3;

I have to do several thousands of these queries.

我必须做几千个这样的查询。

Is there anyway I can "bulk update" lots of rows in one query in PostgreSQL? If you're using INSERT, you can insert multiple rows at once: (INSERT INTO mytable (column_a, column_b) VALUES ( (12, 6), (1, 45) );), Is there something like that for UPDATE?

无论如何,我可以在 PostgreSQL 的一个查询中“批量更新”很多行吗?如果您正在使用INSERT,则可以一次插入多行:( INSERT INTO mytable (column_a, column_b) VALUES ( (12, 6), (1, 45) );),是否有类似的内容UPDATE

Something like:

就像是:

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

??

??

The important points is that each 'VALUE' will only update one row (based on the WHERE id =). Each row will have the same, fixed number of columns that need updating, but each row will have different values for each column, so UPDATE mytable SET column_a = 12, column_b = 6 WHERE id IN (1, 2, 3);won't work.

重要的一点是每个“VALUE”只会更新一行(基于WHERE id =)。每一行都有相同的固定数量的需要更新的列,但每一行的每一列都有不同的值,所以UPDATE mytable SET column_a = 12, column_b = 6 WHERE id IN (1, 2, 3);不起作用。

回答by Roman Pekar

Yes, you can (and usually it's preferred in SQL) to update several rows at once. There're a few ways to do this, but most readable and elegant I think is to use derived table with id's and values:

是的,您可以(并且通常在 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

Not so readable, but more obvious solution would be to use case:

不太可读,但更明显的解决方案是使用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)

回答by Hamlet Hakobyan

If this applicable to your case you can use it.

如果这适用于您的情况,您可以使用它。

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 FIDDLE DEMO

SQL 小提琴演示