这很容易,已被多次询问,但我无法让它工作。 我认为应该工作的SQL查询是:
UPDATE table2
SET dst.a = dst.a + src.a,
dst.b = dst.b + src.b,
dst.c = dst.c + src.c,
dst.d = dst.d + src.d,
dst.e = dst.e + src.e
FROM table2 AS dst
INNER JOIN table1 AS src
ON dst.f = src.f
答案 0 :(得分:25)
使用update语句是不可能的,因为不支持更新语句中的sqlite连接。查看文档: update statement
如果您只想将单个列更新为静态值,则可以在update语句中正确使用子查询。请参阅此示例:How do I make an UPDATE while joining tables on SQLite?
现在在您的示例中,假设“列f”上有唯一键 - 我提出的解决方法/解决方案是使用替换语句:
replace into table2
(a, b, c, d, e, f, g)
select src.a, src.b, src.c, src.d, src.e, dest.f, dest.g
from table1 src
inner join table2 dest on src.f = dest.f
我还在table2“column g”中添加了一个额外的列,以显示如何使用此方法“更新”某些列。
另一件要谨慎的事情是,如果你使用“PRAGMA foreign_keys = ON;”
可以有效地删除和插入行答案 1 :(得分:5)
我想出了一种使用TRIGGER的替代技术并“反转”更新的方向,虽然代价是源表中的虚拟字段。
一般而言,您有一个Master
表和一个Updates
表。您想要通过关键字段Master
链接的Updates
中的相应字段更新Key
中的部分/全部记录字段。
而不是UPDATE Master SET ... FROM Master INNER JOIN Updates ON Mater.Key = Updates.Key
,您可以执行以下操作:
向TriggerField
表添加虚拟字段Updates
以充当触发器的焦点。
在此字段上创建触发器:
CREATE TRIGGER UpdateTrigger AFTER UPDATE OF TriggerField ON Updates
BEGIN
UPDATE Master SET
Field1 = OLD.Field1,
Field2 = OLD.Field2,
...
WHERE Master.Key = OLD.Key
END;
使用以下内容启动更新过程:
UPDATE Updates SET TriggerField = NULL ;
虚拟字段只是触发器的锚点,因此任何其他UPDATE Updates SET ...
都不会触发更新到Master
。如果您只INSERT
进入Updates
,那么您不需要它(并且可以在创建触发器时删除OF TriggerField
子句。)
从一些粗略的准备时间开始,这似乎与REPLACE INTO
的速度大致相同,但避免了删除和添加行的感觉 - 稍微错误的技术。如果您只更新Master
中的几个字段,因为您只列出要更改的字段,这也会更简单。
它比我见过UPDATE ... FROM
的其他替代方案快了几个数量级:
UPDATE Master SET
Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
Field1 = ( SELECT Field1 FROM Updates WHERE Mater.Key = Updates.Key ),
...
;
对于Tony和我的方法,在1700条记录中更新六个字段大致 0.05s ,对于UPDATE ... ( SELECT... )
方法, 2.50s 。
AFTER UPDATE
触发Master
似乎按预期触发。
答案 2 :(得分:3)
正如Tony所说,解决方案是替换为方式,但您可以使用sqlite隐藏字段 rowid 来模拟完整更新,例如:
replace into table2
(rowid,a, b, c, d, e, f, g)
select dest.rowid,src.a, src.b, src.c, src.d, src.e, dest.f, dest.g
from table1 src
inner join table2 dest on src.f = dest.f
如果您没有替换主键或使用连接作为标准方法来执行更新,则可以重新创建完整行。
答案 3 :(得分:2)
SQLITE不支持使用INNER JOIN进行UPDATE,也不支持其他几个DB。内部联接很简单,但只需使用UPDATE和子查询选择即可完成。通过使用where子句和带有子查询的'IN'和'SET'的附加子查询,可以始终实现相同的结果。以下是它的完成方式。
UPDATE table2
SET a = a + (select a from table1 where table1.f = table2.f),
b = b + (select b from table1 where table1.f = table2.f),
c = c + (select c from table1 where table1.f = table2.f),
d = d + (select d from table1 where table1.f = table2.f),
e = e + (select e from table1 where table1.f = table2.f)
WHERE RowId IN (Select table2.RowId from table1 where table1.f = table2.f)
答案 4 :(得分:-5)
使用以下查询:
UPDATE table2
SET a = Z.a,
b = Z.b,
c = Z.c,
d = Z.d,
e = Z.e
FROM (SELECT dst.id,
dst.a + src.a AS a,
dst.b + src.b AS b,
dst.c + src.c AS c,
dst.d + src.d AS d,
dst.e + src.e AS e
FROM table2 AS dst
INNER JOIN table1 AS src ON dst.f = src.f
)Z
WHERE table2.id = z.id