Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLのwith句を使ったupdateについてまとめています。

SQLのwith~updateの文法

with句はサブクエリを簡潔に記述することができます。

【関連記事】
SQLのwith句のサンプル サブクエリを共通テーブル式(CTE)を使って、単純なクエリで記述

以下は、MySQLにて、employees(社員)テーブルの値を取得するサブクエリをwithで定義して、departmetns2(部署)テーブルを更新する例です。

WITH val
     AS (SELECT first_name
         FROM   employees
         WHERE  emp_no = "10001")
UPDATE departments2
SET    dept_name = (SELECT * FROM   val)
WHERE  dept_no = "d001"; 

mysql> select * from departments2;
+---------+--------------------+
| dept_no | dept_name          |
+---------+--------------------+
| d009    | Customer Service   |
| d005    | Development        |
| d002    | Finance            |
| d001    | Georgi             |
| d003    | Human Resources    |
| d004    | Production         |
| d006    | Quality Management |
| d008    | Research           |
| d007    | Sales              |
+---------+--------------------+
9 rows in set (0.00 sec)

社員番号10001の社員のfirst_name(姓名の名)、「Georgi」を、部署テーブルの部署番号d001の値としてupdateしています。更新後のselect文で、更新内容を確認しています。

Oracleのwithを使ったupdate文

UPDATE TESTTBL
   SET STR1 = '1',NUM1 = 1
 WHERE
 STR1 =
 (
    WITH A AS
    (
      SELECT '1' AS STR1
            , 1  AS NUM1
        FROM DUAL
    )
    SELECT STR1
     FROM A
 )


参考)社内SEの徒然なる日記 SQL(Oracle)のUPDATE文でWITH句を使う!

Oracleでも、MySQLのようにwithを使ってupdate文を記述することが可能です。上記の例のように、サブクエリ部分にwithを記述することもできますが、この使い方だとwithを使うメリットがあまりないかも知れません。

Oracleでは、他のDBMSでは動作するコードも、記述方法によってはSyntax Errorとなるケースがあるようです。

SQL Serverのwithを使ったupdate文

USE tempdb;  
GO  
-- UPDATE statement with CTE references that are correctly matched.  
DECLARE @x TABLE (ID INT, Value INT);  
DECLARE @y TABLE (ID INT, Value INT);  
INSERT @x VALUES (1, 10), (2, 20);  
INSERT @y VALUES (1, 100),(2, 200);  
  
WITH cte AS (SELECT * FROM @x)  
UPDATE x -- cte is referenced by the alias.  
SET Value = y.Value  
FROM cte AS x  -- cte is assigned an alias.  
INNER JOIN @y AS y ON y.ID = x.ID;  
SELECT * FROM @x;  
GO  

ID     Value  
------ -----  
1      100  
2      200  
(2 row(s) affected)  

関連)UPDATE (Transact-SQL) – SQL Server | Microsoft Docs

上記は、テーブル@xの値を、結合した別テーブル@yの値で更新する例です。withで定義した共通テーブル式に別名定義(cte AS x)を使う場合、共通テーブル式の記述場所全てに別名を使う必要があります。

MySQLのwithを使ったupdate文

WITH val
     AS (SELECT first_name
         FROM   employees
         WHERE  emp_no = "10001")
UPDATE departments2
SET    dept_name = (SELECT *
                    FROM   val)
WHERE  dept_no = "d001";

WITHを使ったupdate文は、サブクエリに書き直すことが可能です。以下は、setの値指定部分にサブクエリを使った例です。

update departments2
set dept_name=(select first_name from employees where emp_no="10001")
where dept_no="d001";

updateのテーブル指定箇所でサブクエリを使う場合は以下のようになります。

mysql> update departments2, (select first_name from employees where emp_no="10001") tbl2
set dept_name=tbl2.first_name
where dept_no="d001";

【関連記事】
MySQLのupdateでselectした結果を使う方法 サブクエリで自己テーブル更新も可能

いずれも結果は同じで、departmets2(部署)テーブルのd001のdept_name(部署名)が、employees(社員)テーブルのemp_no(社員番号)10001のfirst_name(姓名の名)、「Georgi」で更新されます。

select * from departments2 order by dept_no;
+---------+--------------------+
| dept_no | dept_name          |
+---------+--------------------+
| d001    | Georgi             |
| d002    | Finance            |
| d003    | Human Resources    |
| d004    | Production         |
| d005    | Development        |
| d006    | Quality Management |
| d007    | Sales              |
| d008    | Research           |
| d009    | Customer Service   |
+---------+--------------------+

PostgreSQLのwithを使ったupdate文

with内にupdate文を記述する場合、以下の用に記述することで「updateで更新前の値」と「updateで更新後の値」を取得することができます。

以下のSQLは、updateで更新前の値をselect文で取得します。

WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM products;

以下のSQLは、updateで更新後の値をselect文で取得します。

WITH t AS (
    UPDATE products SET price = price * 1.05
    RETURNING *
)
SELECT * FROM t;

参考)PostgreSQLの公式ドキュメント:WITH問い合わせ(共通テーブル式)

まとめ

ポテパンダの一言メモ
  • withによる共通テーブル式をupdate文と組み合わせて使える
  • OracleなどDBMSによって、withを使った記述に制約があるケースあり
  • postgresqlでは、withを使ってupdate実行前の値と実行後の値を取得できる

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。