これは非常に簡単で、何度も尋ねられましたが、私はそれを機能させることができません。私がうまくいくと思う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
Sqliteではupdateステートメントでの結合がサポートされていないため、updateステートメントを使用することはできません。ドキュメントを参照してください: 更新ステートメント
単一の列を静的な値に更新するだけの場合は、updateステートメントでサブクエリを正しく使用できます。この例を参照してください: SQLiteでテーブルを結合しているときにUPDATEを作成するにはどうすればよいですか?
ここで、あなたの例では、「列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
また、table2の「columng」に列を追加して、このメソッドで一部の列のみを「更新」する方法を示しました。
「PRAGMAforeign_keys = ON;」を使用する場合は、もう1つ注意が必要です。行が効果的に削除および挿入されるため、これに問題が発生する可能性があります。
ソーステーブルのダミーフィールドが犠牲になりますが、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
_とほぼ同じ速度で動作するようですが、feels-slightly-wrongテクニックを回避します行の削除と追加の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 ),
...
;
_
1700レコードを超える6つのフィールドの更新は、Tonyと私のメソッドではおおよそ.05sでしたが、UPDATE ... ( SELECT... )
メソッドでは2.50sでした。
Master
の_AFTER UPDATE
_トリガーは期待どおりに起動するようです。
Tonyが言うように、解決策はreplace intoの方法ですが、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
これを使用すると、置換用の主キーがない場合、または結合を使用して更新を行うための標準的な方法として、完全な行を再作成できます。
SQLITEは、INNER JOINを使用したUPDATEをサポートしておらず、他のいくつかのDBもサポートしていません。内部結合は素晴らしくシンプルですが、UPDATEとサブクエリselectを使用するだけで実行できます。 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)