SQLite的内部连接 ​​- 使用值更新另一个表(SQLite inner join - upda

2019-06-26 17:50发布

这是很容易的,已被要求多次,但我无法得到它的工作。 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

Answer 1:

使用更新语句,因为在源码中的更新语句连接不支持是不可能的。 见文档: update语句

如果你只是想更新单个列静态值,你可以在更新语句中正确使用子查询。 见下面的例子: 我如何进行更新,而在SQLite的连接表?

现在,在你的榜样,做一个假设,即存在于“列F”唯一的密钥 - 一个解决方法/解决方案,我想出了使用REPLACE语句:

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

我还添加了一个额外的列表2“G列”,以显示你怎么会“更新”只有一些用这种方法列。

还有一两件事要谨慎的是,如果你使用“PRAGMA foreign_keys = ON”; 它可能有问题,以此为该行有效地删除和插入。



Answer 2:

我想出了使用触发器和在虚拟场的源表的成本“逆转”的更新的方向,尽管可替代的技术。

一般而言,你有一个Master表和Updates表。 要更新一些/中记录的所有领域的Master从相应字段Updates由键字段链接Key

而不是UPDATE Master SET ... FROM Master INNER JOIN Updates ON Mater.Key = Updates.Key你做到以下几点:

  1. 虚拟字段添加TriggerFieldUpdates表作为触发的焦点。

  2. 建立在这个领域的触发器:

     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; 
  3. 启动与下面的更新过程:

     UPDATE Updates SET TriggerField = NULL ; 

笔记

  1. 空场仅仅是触发锚,使任何其他UPDATE Updates SET ...不会触发更新成Master 。 如果你永远只能INSERTUpdates ,那么你不需要它(并可以删除OF TriggerField创建时触发条款)。

  2. 从一些粗糙和准备好时机,这似乎是大约相同的速度工作REPLACE INTO ,但避免了删除和添加行的感觉,稍微错技术。 这也是简单的,如果你只在更新了数场Master ,你只列出你想改变的人。

  3. 这是数量级比我见过的其他方案快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 ), ... ; 

    更新超过1700条记录六个字段是为托尼和我的方法,但2.50s大约0.05秒UPDATE ... ( SELECT... )方法。

  4. AFTER UPDATE触发器在Master似乎火如预期。



Answer 3:

正如托尼说,解决办法是更换成这样,但你可以使用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

有了这个,你重新整行,如果你不具备的更换或加入做更新的标准方法的主键。



Answer 4:

SQLite不支持的更新与INNER JOIN也没有其他几个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) 


Answer 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


文章来源: SQLite inner join - update using values from another table