使用 unnest 在 postgreSQL 中批量更新

Bulk update in postgreSQL using unnest

我正在尝试进行批量更新:

> update ti_table set enabled=T.enabled 
    from (select * from 
         unnest(array['2001622', '2001624', '2007903']) as id,
         unnest(array[15,14,8]) as ver,
         unnest(array['type1', 'type1', 'type1']) as type,
         unnest(array[false, true, true]) as enabled) T 
    where ti_table.id=T.id AND ti_table.ver=T.ver AND ti_table.type=T.type;

然而,当我回头阅读时:

> select id, ver, type, enabled from ti_table where id in ('2001622', '2001624', '2007903');

我明白了:

   id    | ver | type  | enabled 
---------+-----+-------+---------
 2001622 |  15 | type1 | f
 2001624 |  14 | type1 | f
 2007903 |   8 | type1 | f

最后两行 enabledfalse 而我预计它是 true

为什么会发生这种情况,我该如何正确处理?

谢谢。

您可以使用 PostgreSQL VALUES:

UPDATE ti_table ti
SET enabled = data.enabled
FROM (
  VALUES
    ('2001622', 15, 'type1', false),
    ('2001624', 14, 'type1', true),
    ('2007903', 8, 'type1', true)
) AS data(id, ver, type, enabled)
WHERE ti.id = data.id
AND ti.ver = t.ver
AND ti.type = data.type;

它更易于阅读,因为值按行分组在一起。

您在 FROM 子句上调用了 unnest 3 次,这意味着您正在执行 3.

CROSS JOIN(笛卡尔积)

如果您使用的是 PostgreSQL 9.4 或更高版本,您可以简单地执行一次 unnest 调用,将每个数组作为输入:

select * from 
         unnest(
            array['2001622', '2001624', '2007903'],
             array[15,14,8],
             array['type1', 'type1', 'type1'],
             array[false, true, true]
        ) as u(id, ver, type, enabled)

对于任何版本,另一个选项是在 SELECT 中添加对 unnest 的调用,而不是 FROM:

select
   unnest(array['2001622', '2001624', '2007903']) as id,
   unnest(array[15,14,8]) as ver,
   unnest(array['type1', 'type1', 'type1']) as type,
   unnest(array[false, true, true]) as enabled

在这两种情况下,但特别是在最后一种情况下,您必须确保每个数组都具有完全相同数量的元素。如果不是在第一种方法中,每个缺失的行将被填充为 NULL,但第二个方法将 return 行数与 returned 行数的 LCM 一样多每一个,你可能不想要的。示例:

SELECT * FROM unnest(array[1,2,3,4], array['a','b','c','d','e','f']);
 unnest | unnest 
--------+--------
      1 | a
      2 | b
      3 | c
      4 | d
 [null] | e
 [null] | f
(6 rows)

SELECT unnest(array[1,2,3,4]), unnest(array['a','b','c','d','e','f']);
 unnest | unnest 
--------+--------
      1 | a
      2 | b
      3 | c
      4 | d
      1 | e
      2 | f
      3 | a
      4 | b
      1 | c
      2 | d
      3 | e
      4 | f
(12 rows)

查看 table functions calls 上的文档以获取更多信息。