web-dev-qa-db-ja.com

1つのSQLステートメントで複数の行の複数の列を更新する方法

SQL Serverデータベースで、複数の行の列を更新したいと考えています。私は1行だけにそれを行うことができます:

UPDATE theTable
SET theColumn = case
WHEN id = 1 then 'a' 
WHEN id = 2 then 'b'
WHEN id = 3 then 'c'
WHERE id in (1, 2, 3)

同じクエリでより多くの列(theColumn2、theColumn3 ...)を更新するにはどうすればよいですか?

3
mohamed

これを行う方法の例(SQLFiddle here を参照):

(ps私は [〜#〜] cte [〜#〜] (別名WITH句)とPostgreSQLを使用しました(MS SQL Serverは使用していません)しかし、原則はほとんど同じです-SERIALデータ型を除いて-MSの自動インクリメントタイプを使用してください!)。

ソーステーブル(名前付き)を作成してデータを入力します。

CREATE TABLE one
(
  record_id SERIAL,
  one_first_var INTEGER,
  one_second_var INTEGER,
  one_third_var INTEGER
);

INSERT INTO one (one_first_var, one_second_var, one_third_var) VALUES (1, 1, 1);
INSERT INTO one (one_first_var, one_second_var, one_third_var) VALUES (2, 2, 2);
INSERT INTO one (one_first_var, one_second_var, one_third_var) VALUES (3, 3, 3);

また、ターゲットテーブル(2つ):

CREATE TABLE two
(
  record_id SERIAL,
  two_first_var INTEGER,
  two_second_var INTEGER,
  two_third_var INTEGER
);

INSERT INTO two (two_first_var, two_second_var, two_third_var) VALUES (21, 21, 21);
INSERT INTO two (two_first_var, two_second_var, two_third_var) VALUES (22, 22, 22);
INSERT INTO two (two_first_var, two_second_var, two_third_var) VALUES (23, 23, 23);

(表2の値を再確認してください):

SELECT * FROM two;

次に、更新を実行します(一度に複数の列)。

WITH my_values AS
(
  SELECT 
         one_first_var, 
         one_second_var, 
         one_third_var
  FROM one
  WHERE one_first_var = 2
)
UPDATE two 
SET 
  two_first_var = my_values.one_first_var,
  two_second_var = my_values.one_second_var,
  two_third_var = my_values.one_third_var
FROM
  my_values
WHERE
  two_second_var = 22;

そして、あなたの再実行

SELECT * FROM two;

もう一度、 SQLFiddle を参照してください。

JOINを使用して、ターゲットレコードを更新することもできます。これらのテクニックを試してみることをお勧めします-非常に便利です!

2つの最初の結果(つまり、挿入された値)は次のようになります。

record_id   two_first_var   two_second_var  two_third_var
        1              21               21             21
        2              22               22             22
        3              23               23             23

2番目の(更新された)結果は次のようになります。

record_id   two_first_var   two_second_var  two_third_var
        2               2                2              2
        1              21               21             21
        3              23               23             23
5
Vérace

新しい値をテーブルとして( [〜#〜] values [〜#〜] 行コンストラクターを使用して)提供できるため、ターゲットテーブルと結合して、次のように、UPDATEステートメントに参加します。

UPDATE
  tgt
SET
  Column1 = src.Column1,
  Column2 = src.Column2,
  Column3 = src.Column3,
  ...
FROM
  dbo.TargetTable AS tgt
  INNER JOIN
  (
    VALUES
    (1, 'a', 'k', 'x', ...),
    (2, 'b', 'l', 'y', ...),
    (3, 'c', 'm', 'z', ...)
  ) AS src (ID, Column1, Column2, Column3, ...)
    ON tgt.ID = src.ID
;
4
Andriy M