更新一个表的字段值等于另一个表的字段值的SQL语句要怎么写?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了更新一个表的字段值等于另一个表的字段值的SQL语句要怎么写?相关的知识,希望对你有一定的参考价值。
表 A[A1,A2] B[B1,B2] 所有字段都是字符型的!
执行条件:如果 A1=B1 时更新 A2=B2
这样的更新语句怎么写呀?
a
set
a.ty2=b.ty1
from
t2
a,t1
b
where
a.n2=b.n1
--保证没有问题,不信可以先测试一下 参考技术B 方法有很多种
但是其实都是一种思路
无外乎更新表A 即 update A
更新字段A2 即 set A2=B2
连接表A和表B 即 A join B on A.A1=B.B1 参考技术C create view v
as
select a.a1,a.a2,b.b1,b.b2 from a inner join b on a.a1=b.b1;
go
update v set a2=b2 where a1=b1
go本回答被提问者采纳 参考技术D updata a ,b
set a.a2=b.b2
where a.a1=b.b1 第5个回答 2009-10-29 update A.A2=B.B2 from A,B where A.A1=B.B1
SQL 从另一个表的字段更新一个表的字段
【中文标题】SQL 从另一个表的字段更新一个表的字段【英文标题】:SQL update fields of one table from fields of another one 【发布时间】:2011-02-15 08:51:15 【问题描述】:我有两张桌子:
A [ID, column1, column2, column3]
B [ID, column1, column2, column3, column4]
A
将始终是B
的子集(意味着A
的所有列也在B
中)。
我想用来自A
的A
的所有列的B
中的特定ID
更新记录。这个ID
存在于A
和B
中。
是否有UPDATE
语法或任何其他方法可以在不指定列名的情况下做到这一点,只需说“设置 A 的所有列”?
我使用的是 PostgreSQL,因此也接受特定的非标准命令(但是,不是首选)。
【问题讨论】:
我想这就是你想做的,dba.stackexchange.com/a/58383 【参考方案1】:您可以使用非标准的FROM 子句。
UPDATE b
SET column1 = a.column1,
column2 = a.column2,
column3 = a.column3
FROM a
WHERE a.id = b.id
AND b.id = 1
【讨论】:
问题是询问如何不指定所有列名。 (我也是。) 我同意@cluesque,但这个答案是使用表中一列中的值作为查找表以替换另一个表中列中的值的绝佳方法(请参阅SO 21657475),所以+1 ... 为什么需要 b.id = 1 ? @YasirAzgar b.id = 1 是为了限制 b 中的哪些行被更新。否则我们将更新表中的每一行。有时,这可能是您想要的。但最初的问题是更新 b 中的特定行。 这是我解决特定问题所需要的:使用来自另一个表的不同名称列的值更新一个表的列。【参考方案2】:这个问题很老了,但我觉得还没有给出最好的答案。
是否有
UPDATE
语法...没有指定列名?
使用动态 SQL 的一般解决方案
您不需要知道任何列名,除了一些要加入的唯一列(示例中为id
)。对于我能想到的任何可能的极端情况都可靠地工作。
这是 PostgreSQL 特有的。我正在构建基于information_schema 的动态代码,特别是在SQL 标准中定义的表information_schema.columns
,大多数主要的RDBMS(Oracle 除外)都有它。但是带有PL/pgSQL 代码执行动态SQL 的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
中的列与a
中的每个 列匹配,但反之则不然。 b
可以有额外的列。
WHERE b.id = 123
是可选的,用于更新选定的行。
db小提琴here旧sqlfiddle
更多解释的相关答案:
Dynamic UPDATE fails due to unwanted parenthesis around string in plpgsql Update multiple columns that start with a specific string使用纯 SQL 的部分解决方案
带有共享列列表
您仍然需要知道两个表共享的列名列表。使用用于更新多列的语法快捷方式 - 在任何情况下都比迄今为止建议的其他答案短。
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;
db小提琴here旧sqlfiddle
这种语法是在 2006 年的 Postgres 8.2 中引入的,早在问这个问题之前。 Details in the manual.
相关:
Bulk update of all columns
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 JOIN
连接来自b
的行,其中所有同名的列都包含相同的值。在这种情况下,我们不需要更新(没有任何变化),并且可以在流程的早期消除这些行 (WHERE b.id IS NULL
)。
我们仍然需要找到匹配的行,所以在外部查询中使用b.id = ab.id
。
db小提琴here旧sqlfiddle
这是标准 SQL except for the FROM
clause。
无论A
中实际存在哪些列,它都有效,但查询无法区分A
中的实际NULL 值和缺失列,因此只有在A
中的所有列都定义NOT NULL
时才可靠.
有多种可能的变体,具体取决于您对这两个表的了解。
【讨论】:
SQL 的强大功能!刚刚注意到,当您在 set 子句中添加括号时 (SET (column1) = (a.column)
),Postgres 会将其视为另一种更新,并给出如下错误:source for a multiple-column UPDATE item must be a sub-SELECT or ROW() expression
【参考方案3】:
我已经使用 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
注意:主要问题是 FROM 原因,DB2 不支持,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)
【讨论】:
请注意,第二个和第三个查询并不完全等同于第一个。如果在B
中没有找到匹配的行,则第一个语句执行nothing(原始行保持不变),而其他两个用NULL 值覆盖列。【参考方案4】:
这是一个很大的帮助。代码
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
让它工作。
【讨论】:
【参考方案5】:不一定是你问的,但也许使用 postgres 继承可能会有所帮助?
CREATE TABLE A (
ID int,
column1 text,
column2 text,
column3 text
);
CREATE TABLE B (
column4 text
) INHERITS (A);
这避免了更新 B 的需要。
但请务必阅读所有details。
否则,您的要求不被认为是一种好的做法 - 不鼓励使用动态内容,例如带有 SELECT * ...
的视图(因为这种轻微的便利可能会破坏更多的东西而不是帮助的东西),而您所要求的将等同于UPDATE ... SET
命令。
【讨论】:
我不确定继承如何解决这个问题。你的意思是为 A 添加一个更新触发器也更新 B?我不想一直将 A 与 B 同步,仅应请求。在这种情况下,我不能使用触发器。 是的,如果仅在某些情况下,继承将不起作用,在这种情况下,我建议不要使用动态查询方法。 (仍然有一些方法可以使用 postgres 程序语言来实现这一点。如果你想使用触发器,你也可以使用它们 - 通过添加同步字段,例如仅在设置时触发触发器)。【参考方案6】:您可以构建并执行动态 sql 来执行此操作,但这确实不理想
【讨论】:
我想过。我以为我可以使我的查询符合以后对两个表的更改,但是动态 sql 似乎太复杂了,而不是只指定所有字段而忘记前向兼容性。 是的,它会很复杂,但应该与以后添加或删除的列向前兼容。您必须首先进行查询以从两个表中获取列名,然后匹配列名,然后编写动态 sql 以根据匹配的列名进行更新。实际上是一个有趣的项目:)【参考方案7】:尝试关注
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
【讨论】:
我不明白它是如何复制 column1、column2 和 column3 的。我确实需要明确提及第 1 列。 对我不起作用。我收到以下错误:错误:“,”或附近的语法错误 这种非标准语法适用于UPDATE
in MySQL,但对PostgreSQL无效。以上是关于更新一个表的字段值等于另一个表的字段值的SQL语句要怎么写?的主要内容,如果未能解决你的问题,请参考以下文章
SQL语句 一个表的值与另一个表的字段一致,怎么把两一个表的值作为条件,限定查询的字段
mysql如何更新一个表中的某个字段值等于另一个表的某个字段值