我正在尝试批量更新:
> 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
最后两行启用为false
,而我预计会true
为什么会发生这种情况,我该如何正确地做到这一点?
感谢。
答案 0 :(得分:3)
您在unnest
条款上调用FROM
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)
对于任何版本,另一个选项是将调用添加到unnest
而不是SELECT
中的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,但第二个它将返回与每个返回的行数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上的文档以获取更多信息。
答案 1 :(得分:2)
你可以使用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;
它更容易阅读,因为值按行组合在一起。