CASEを使用してUPDATEクエリの列を選択しますか?


13

次のようCASEに、SELECTクエリに表示する列を選択するために使用できます(Postgres)。

SELECT CASE WHEN val = 0 THEN column_x
            WHEN val = 1 THEN column_y
            ELSE 0
       END AS update, ...

UPDATEPostgresでクエリを実行するときに、同様のことは可能ですか(更新する列を選択してください)。私はこれについて何も見つけることができなかったのではないと思いますが、誰かが賢い代替手段を持っていると思います(手順を使用するか、CASEを使用して各列を更新して、列の値に新しい値を割り当てるか、単に既存の列を再割り当てするかを決定する以外に値)。簡単な選択肢がない場合は、もちろんそれも答えとして受け入れます。

追加情報:私の場合、更新される可能性のある14の潜在的な列があり、一致する行ごとに1つだけが更新されます(更新されるテーブルはクエリで別のテーブルと結合されます)。更新する行の量はおそらく異なり、数十または数百になる可能性があります。結合条件の指標は整っていると思います。

回答:


26

あなたは、列を指定した場合に更新する必要があり、それは常に更新されます、しかし、あなたは条件付きで入れて値を変更し、あなたの条件に応じて、元の値を戻すことができます。何かのようなもの:

UPDATE some_table
SET    column_x = CASE WHEN should_update_x THEN new_value_for_x ELSE column_x END
     , column_y = CASE WHEN should_update_y THEN new_value_for_y ELSE column_y END
     , column_z = CASE WHEN should_update_z THEN new_value_for_z ELSE column_z END
FROM   ...

したがって、特定の列の更新に条件が適切でない場合は、現在の値をフィードバックするだけです。

ONとWHERE句のフィルタリングでこの状況を明示的にゲートしない限り、一致するすべての行で更新表示されます(すべての列が最終的にすでに設定されている値に設定される場合でも)。これは、パフォーマンスの問題となる可能性があります(書き込みである場合、インデックスが更新され、適切なトリガーが起動されます...軽減されない場合。


すべてが更新されていることについてのヒントをありがとう、これが遅い場合は、@ Colin 't Hartの提案に従って複数の更新ステートメントを作成することができます。
newenglander 2013

ONとWHERE句で変更が不要なすべての行を確実に除外することで、この問題を完全に緩和できますが、SET句とWHERE句の両方ですべての条件を繰り返すことを意味する場合があります(簡単な全体チェックがない限り、これらの条件をすべて組み合わせたものに100%相当です)。この時点では、この方法の方が効率的ですが、複数の更新方法の方が管理が簡単です。
David Spillett 2013

列を同じ値に更新すると、REDOが作成されることにも注意してください。orainternals.wordpress.com/ 2010/11/04 /…を
Colin 't Hart

@Colin:ええ、更新は、フィールドが以前と同じ値になるように更新するため、本質的にNoOpsである更新を含む、DBのトランザクションログを通過します。レプリケーション、差分バックアップ、ログ配布などを使用する場合、追加の行更新操作によってそれらに必要なスペース/帯域幅が増加するため、即時のパフォーマンス問題の可能性と同様に、これは重要な要素になる可能性があります。
David Spillett、2013

ヒントを教えてくれたあなたの両方に感謝します。私の場合、単一の更新ステートメントはうまくいきました。
newenglander 2013

5

更新する列の組み合わせはいくつありますか?テーブル全体の何行が更新されますか?更新する行への高速アクセスのためにインデックスが設定されていますか?

これらの質問に対する回答によっては、更新する列ごとに1つずつ、複数の更新ステートメントを実行し、更新のwhere句でその列の値に条件を設定して、その列の場合に行が更新されないようにすることができます。値が間違っています。

セットベースで試してみてください。更新で主キーによって検出された単一の行を更新する必要があると想定しないでください。


答えてくれてありがとう。質問にさらに情報を追加しました。理解できるといいのですが。これは、複数の更新ステートメントを使用する優れた代替策です(私は1つの更新ステートメントが望ましいですが、そこに利点があると思います)。
newenglander 2013

これは私が探している答えかもしれませんが、update column_x = new_value_for_x where @val = 0を置くつもりですか。面白いですね。もしヴァル= 0更新column_x = new_value_for_xなどを開始行うことが容易にIsin't
CashCow

-1
update Practicing  -- table you will be updating
 set email = case -- column you will be updating
    when FName = 'Glenn' then 'Ace@Assasin.com'
       when FName = 'Riddick' then 'fallguy@Drunk.com'
       when FName = 'Jeffrey' then 'sorcerer@wizcom'
       else email
    end

これは単一の列のみを更新しますが、質問者は条件に応じて異なる列を更新する方法を知りたいです。
Colin 't Hart
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.