32

我想将val1表的一列中的所有值复制到另一表table1的一列。我在 PostgreSQL 中尝试了这个命令:val2table2

update table2
set val2 = (select val1 from table1)

但我得到了这个错误:

ERROR:  more than one row returned by a subquery used as an expression

有替代方法吗?

4

2 回答 2

77

您的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, see below

按照您的方式,两个表的各个行之间没有链接。table1每一行都会从table2. 这没有意义(以昂贵的方式)并且还触发了语法错误,因为这个地方的子查询表达式只允许返回单个值。

我通过加入两个表来解决这个问题table2_id。将其替换为实际链接两者的任何内容。

我重写了UPDATE加入table1(使用FROM子句)而不是运行相关的子查询,因为这通常快一个数量级。
它还可以防止table2.val2table1. 相反,使用这种形式的查询不会对此类行产生任何影响。

您可以将表表达式添加到FROM列表中,就像在普通SELECT(表,子查询,集合返回函数,...)中一样。手册:

from_list

表表达式列表,允许其他表中的列出现在WHERE条件和更新表达式中。这类似于可以在语句的FROM子句 中指定的表列表SELECT。请注意,目标表不得出现在 中from_list,除非您打算进行自联接(在这种情况下,它必须在 中出现别名from_list)。

最后一个WHERE子句阻止不会改变任何东西的更新——这实际上总是一个好主意(几乎全部成本但没有收益,外来例外适用)。如果新旧值都保证为NOT NULL,则简化为:

AND   t2.val2 <> t1.val1
于 2012-11-20T12:55:11.240 回答
0

从 table2 table2 更新 table1 set table1_column= table2.column where table1_id= table2.id

  1. 不要为 table1 使用别名。
  2. 表是表1,表2
于 2016-06-24T07:20:20.253 回答