SQL更新另一个字段的一个表的字段

我有两个表格:

A [ID, column1, column2, column3] B [ID, column1, column2, column3, column4] 

A将永远是B子集(意味着A所有列也都在B )。

我想用A中所有列的A的数据更新B具有特定ID的logging。 此ID存在于AB

有没有UPDATE语法或任何其他方式来做到这一点,而不指定列名称,只是说“设置A的所有列”

我正在使用PostgreSQL,所以一个特定的非标准命令也被接受(但不是首选)。

您可以使用非标准的FROM子句。

 UPDATE b SET column1 = a.column1, column2 = a.column2, column3 = a.column3 FROM a WHERE a.id = b.id AND b.id = 1 

这个问题很老,但我觉得还没有给出最好的答案。

有没有UPDATE语法… 没有指定列名称

一般解决scheme与dynamicSQL

你不需要知道任何列名,除了一些独特的列join(在例子中的id )。 可以为任何可能的angular落案例可靠地工作,我能想到的。

这是PostgreSQL特有的。 我正在构build基于information_schema的dynamic代码,特别是在ANSI SQL中定义的表information_schema.columns以及大多数现代的RDBMS(Oracle除外)都支持它。 但是执行dynamicSQL的PL / pgSQL代码的DO语句完全是非标准的PostgreSQL语法。

 DO $do$ BEGIN EXECUTE ( SELECT 'UPDATE b SET (' || string_agg(quote_ident(column_name), ',') || ') = (' || string_agg('a.' || quote_ident(column_name), ',') || ') FROM a WHERE b.id = 123 AND a.id = b.id' FROM information_schema.columns WHERE table_name = 'a' -- table name, case sensitive AND table_schema = 'public' -- schema name, case sensitive AND column_name <> 'id' -- all columns except id ); END $do$; 

假设b中的每一都有一个匹配的列,但是不是相反的。 b可以有额外的列。

WHERE b.id = 123是可选的,只更新选定的行。

SQL小提琴。

更多解释的相关答案:

  • dynamic更新因plpgsql中的string周围不需要的括号而失败
  • 更新多个以特定string开头的列

部分解决scheme与普通的SQL

与共享列的列表

您仍然需要知道这两个表共享的列名称的列表。 使用更新多列的语法快捷方式 – 比任何情况下build议的其他答案都要短。

 UPDATE b SET ( column1, column2, column3) = (a.column1, a.column2, a.column3) FROM a WHERE b.id = 123 -- optional, to update only selected row AND a.id = b.id; 

SQL小提琴。

这个语法是在2006年12月在Postgres 8.2中引入的,早在问题被提出之前。
本手册中的更多细节以及与dba.SE相关的解答:

  • 批量更新所有列

B列的列表

如果 A所有列都定义了NOT NULL (但不一定是B ),
知道 B的列名(但不一定是A )。

 UPDATE b SET (column1, column2, column3, column4) = (COALESCE(ab.column1, b.column1) , COALESCE(ab.column2, b.column2) , COALESCE(ab.column3, b.column3) , COALESCE(ab.column4, b.column4) ) FROM ( SELECT * FROM a NATURAL LEFT JOIN b -- append missing columns WHERE b.id IS NULL -- only if anything actually changes AND a.id = 123 -- optional, to update only selected row ) ab WHERE b.id = ab.id; 

NATURAL LEFT JOINb连接一行,其中所有同名的列保持相同的值。 在这种情况下,我们不需要更新(没有任何更改),并可以在进程的早期消除那些行( WHERE b.id IS NULL )。
我们仍然需要find一个匹配的行,所以外部查询中的b.id = ab.id

SQL小提琴。

除了FROM子句,这是标准的SQL。
它可以工作,不pipe哪一列实际存在于A ,但查询不能区分实际的NULL值和A缺失列,所以只有在A中的所有列都定义为NOT NULL情况下才是可靠的。

有多种可能的变化,这取决于你知道两个表。

我已经使用IBM DB2数据库十多年了,现在正在努力学习PostgreSQL。

它适用于PostgreSQL 9.3.4,但不适用于DB2 10.5:

 UPDATE B SET COLUMN1 = A.COLUMN1, COLUMN2 = A.COLUMN2, COLUMN3 = A.COLUMN3 FROM A WHERE A.ID = B.ID 

注意:主要问题是DB2中不支持的FROM原因,也不是ANSI SQL中的原因。

它适用于DB2 10.5,但不适用于PostgreSQL 9.3.4:

 UPDATE B SET (COLUMN1, COLUMN2, COLUMN3) = (SELECT COLUMN1, COLUMN2, COLUMN3 FROM A WHERE ID = B.ID) 

最后! 它适用于PostgreSQL 9.3.4和DB2 10.5:

 UPDATE B SET COLUMN1 = (SELECT COLUMN1 FROM A WHERE ID = B.ID), COLUMN2 = (SELECT COLUMN2 FROM A WHERE ID = B.ID), COLUMN3 = (SELECT COLUMN3 FROM A WHERE ID = B.ID) 

不一定你问什么,但也许使用postgresinheritance可能有帮助?

 CREATE TABLE A ( ID int, column1 text, column2 text, column3 text ); CREATE TABLE B ( column4 text ) INHERITS (A); 

这避免了需要更新B.

但一定要阅读所有的细节 。

否则,你所要求的是不被认为是一个好的做法 – dynamic的东西,如与SELECT * ...意见是不鼓励的(因为轻微的便利可能会打破更多的东西,而不是帮助的东西),你要求的是相当于UPDATE ... SET命令。

这是一个很大的帮助。 代码

 UPDATE tbl_b b SET ( column1, column2, column3) = (a.column1, a.column2, a.column3) FROM tbl_a a WHERE b.id = 1 AND a.id = b.id; 

完美的作品。

注意到你需要一个括号“”

 From "tbl_a" a 

使其工作。

你可以build立和执行dynamicsql来做到这一点,但它真的不理想

尝试以下

 Update A a, B b, SET a.column1=b.column1 where b.id=1 

编辑: – 更新多个列

 Update A a, B b, SET a.column1=b.column1, a.column2=b.column2 where b.id=1