概要
2つ以上のテーブルを結合し、結合できたデータでUpdateをかけたいことがある。 その場合、「update from」構文を使えば他のテーブルのデータを使ってUpdateすることができる。
構文
以下のような「update from」構文にすれば結合したテーブルのデータを使うのと同じ意味になる。 更新対象のテーブルと結び付けるための条件はon句ではなく where句に記載しなければならないことに注意する。
update
table1
set
column1 = A.column2
, column3 = A.column4 ...
from
table2 A
where
table1.column5 = A.column6
and table1.column7 = A.column_name8 ...
実行例
環境
- Windows 10 64bit
- SQLite3 (3.36.0) Command-Line Shell
product_id | name | quantity |
---|---|---|
1 | tomato | 100 |
2 | potato | 100 |
3 | pumpkin | 50 |
create_date | product_id | quantity |
---|---|---|
2020-10-14 | 2 | 30 |
2020-10-14 | 3 | 100 |
productテーブルをnew_dataテーブルのデータで更新する
update
product
set
quantity = new_data.quantity
from
new_data
where
product.product_id = new_data.product_id
product_id primary key |
name | quantity |
---|---|---|
1 | tomato | 100 |
2 | potato | 30 |
3 | pumpkin | 100 |
where句にはテーブル名を指定すること
where句でカラムを指定する際、更新対象のテーブル名を省略せずに記載する。 例えば以下のようにwhere句を指定するとエラーになる。
sqlite> update
...> product
...> set
...> quantity = new_data.quantity
...> from
...> new_data
...> where
...> product_id = new_data.product_id;
Error: ambiguous column name: product_id
sqlite> update
...> product A
...> set
...> A.quantity = B.quantity
...> from
...> new_data B
...> where
...> A.product_id = B.product_id;
Error: near "A": syntax error
さらに結合するテーブルを増やす場合
from句の後にselect文と同じように「join~on~」を使えばいい。
update
table1
set
column1 = table2.column2
, column3 = table3.column_name4 ...
from
table2
inner join
table3
on
table2.column5 = table3.column6
and table2.column7 = table3.column8 ...
left join
table4
on
table3.column9 = table4.column10
or table4.column11 = "XXX" ...
where
table1.column12 = table2.column13
and table1.column14 = table3.column15 ...
実行例
環境
- Windows 10 64bit
- SQLite3 (3.36.0) Command-Line Shell
サンプルテーブル
product_id | product_name |
---|---|
1 | tomato |
2 | potato |
3 | pumpkin |
create_data | product_id | price |
---|---|---|
2021-08-01 | 2 | 30 |
2021-08-01 | 3 | 100 |
user_id | product_name | price | create_date |
---|---|---|---|
0001 | tomato | 98 | 2021-07-31 |
0001 | pumpkin | 55 | 2021-07-31 |
0002 | tomato | 102 | 2021-08-01 |
0003 | potato | 120 | 2021-08-01 |
「product_name」と「create_date」を条件に 「receipt」テーブルの「price」を 「new_data」テーブルの「price」でアップデートする。
update
receipt
set
price = product.quantity
from
product
inner join
new_data
on
product.product_id = new_data.product_id
where
receipt.product_name = product.product_name
and receipt.insert_date = new_data.create_date
;
結果
user_id | product_name | price | create_date |
---|---|---|---|
0001 | tomato | 98 | 2021-07-31 |
0001 | pumpkin | 55 | 2021-07-31 |
0002 | tomato | 102 | 2021-08-01 |
0003 | potato | 100 | 2021-08-01 |
同じ条件のデータが複数になった場合
where句で指定する条件が同じになるデータが複数になってしまった場合、 どのデータを更新先のテーブルに反映させるかを選択することが 出来ない。
product_id primary key autoincrement |
name not null |
quantity default 0 |
remark |
---|---|---|---|
1 | tomato | 100 | |
2 | potato | 100 | |
3 | pumpkin | 50 | (Comment...) |
create_date | product_id | quantity | remark |
---|---|---|---|
2020-10-14 | 2 | 30 | new comment 01 |
2020-10-14 | 3 | 100 | new comment 02 |
2020-10-15 | 3 | 200 | new comment 03 |
update
product
set
quantity = A.quantity
, remark = A.remark
from
new_data as A
where
product.product_id = A.product_id
product_id primary key autoincrement |
name not null |
quantity default 0 |
remark |
---|---|---|---|
1 | tomato | 100 | |
2 | potato | 30 | new comment 01 |
3 | pumpkin | 200 | new comment 03 |
上記の例だと、new_dataテーブルにproduct_id=3 のデータが2行あるが、
反映されるデータを指定することはできず、いずれかのデータが自動的に反映される。
サブクエリの内容はwhere句で指定した項目でユニークになるよう注意すること。
サブクエリの方が使いやすい
from句で指定するデータは、select文のサブクエリを作った方がデバッグやリファクタリングもしやすいのでおすすめ。
SQLite 3 Selectした結果でUpdateする (update from)
参考URL
-
SQLite 公式サイト(英語)
https://www.sqlite.org/index.html -
2.2 UPDATE FROM (英語)
公式のUPDATE~FROMに関するドキュメント
https://www.sqlite.org/lang_update.html#upfrom