15

これは非常に簡単で、何度も尋ねられましたが、私はそれを機能させることができません。動作するはずの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
4

5 に答える 5

28

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」に列を追加して、このメソッドで一部の列のみを「更新」する方法を示しました。

注意すべきもう1つのことは、「PRAGMAforeign_keys=ON;」を使用する場合です。行が効果的に削除および挿入されるため、これに問題が発生する可能性があります。

于 2012-08-23T20:48:06.733 に答える
5

ソーステーブルのダミーフィールドを犠牲にして、TRIGGERを使用し、更新の方向を「逆にする」代替手法を思いつきました。

一般的に、MasterテーブルとテーブルがありUpdatesます。キーフィールドによってリンクされてMasterいる対応するフィールドから、レコードの一部/すべてのフィールドを更新する必要があります。UpdatesKey

あなたの代わりにUPDATE Master SET ... FROM Master INNER JOIN Updates ON Mater.Key = Updates.Key以下を行います:

  1. トリガーのフォーカスとして機能するダミーフィールドTriggerFieldをテーブルに追加します。Updates

  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。あなたがこれまでにしかINSERT入っていないのであればUpdates、それは必要ありません(そして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レコードを超える6つのフィールドの更新は、Tonyと私のメソッドでは約0.05秒でしたが、メソッドでは2.50秒でしたUPDATE ... ( SELECT... )

  4. AFTER UPDATEのトリガーはMaster期待どおりに起動するようです。

于 2014-03-18T14:03:18.973 に答える
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

これを使用すると、置換用の主キーがない場合、または結合を使用して更新を行うための標準的な方法として、完全な行を再作成できます。

于 2013-11-28T00:15:50.843 に答える
2

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) 
于 2014-10-01T04:23:11.647 に答える
-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
于 2012-08-25T06:45:45.413 に答える