我想将表val1
的一列table1
中的所有值复制到另一个表val2
的一列table2
。我在PostgreSQL中试过这个命令:
update table2
set val2 = (select val1 from table1)
但我收到了这个错误:
错误:用作表达式
的子查询返回多行
有替代方法吗?
答案 0 :(得分:53)
您的UPDATE
查询应该如下所示:
UPDATE table2 t2
SET val2 = t1.val1
FROM table1 t1
WHERE t2.table2_id = t1.table2_id
AND t2.val2 IS DISTINCT FROM t1.val1 -- optional, to avoid empty updates
你拥有它的方式,两个表的各行之间没有链接。对于table1
中的每一行,将从table2
获取每一行。这没有任何意义(以昂贵的方式)并且还触发了语法错误,因为这个地方的子查询表达式只允许返回单个值。
我通过加入table2_id
上的两个表来解决这个问题。将其替换为实际链接两者的内容。
我重新编写UPDATE
以加入table1
(使用FROM
子句)而不是运行相关子查询,因为这通常会更快一个数量级。<登记/>
如果在table2.val2
中找不到匹配的行,它还会阻止table1
无效。相反, nothing 会发生这种形式的查询行。
您可以在普通FROM
中包含的SELECT
列表中包含所有相同的内容(如多个表或子查询)。 Per documentation:
的 from_list 强>表表达式列表,允许其他表中的列 出现在
WHERE
条件和更新表达式中。这是 类似于FROM
Clause中可以指定的表格列表 一个SELECT
声明。请注意,目标表不得出现在 from_list ,除非您打算自行加入(在这种情况下必须 在 from_list 中显示别名。
WHERE
条款会阻止不会改变任何内容的更新 - 这实际上总是一个好主意(全部费用,但没有收益 - 异乎寻常的例外适用)。答案 1 :(得分:0)
更新table1 set table1_column = table2.column from table2 table2 where table1_id = table2.id