概要
selectしたデータを使って updateをするためのSQL。
selectとupdateを別々のSQLで実行するのではなく、同時に実行することができる。
専用の「update~from」構文がsqlite のバージョン3.33.0 から利用可能。
バージョン3.32.0未満場合は以下を参照のこと。
SQLite3 SelectしたデータでUpdateする(~ver 3.29.0)
構文
「update~from」の構文は以下の通り。
selectで取得する内容はサブクエリと同じように書けばいい。 更新先のテーブルの内容を含んでいてもいい。
update
tableA
set
column1 = B.column2
, column3 = B.column4 ...
from (
select
column2
, column4 ...
from
tableB
) as B
where
tableA.column5 = B.column6
実行例
環境
- Windows 10 64bit
- SQLite3 (3.33.0) Command-Line Shell
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-14 | 4 | 200 | new comment 03 |
productテーブルをnew_dataテーブルのデータで更新する
update
product
set
quantity = A.quantity
, remark = A.remark
from (
select
product_id
, quantity
, 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 | 100 | new comment 02 |
使われないデータがあってもエラーにならない
上記の例だとproductテーブルにはproduct_id=4のデータがないため、 new_dataテーブルのproduct_id=4のデータは反映されない。 この際エラーメッセージ等は表示されないため、大量のデータを処理した時に気づきにくい。 厳密に処理するのなら、事前にチェックするか外部キー制約等を利用する必要がある。
selectした結果でupdateとinsertを一括で行いたい場合は 「replace」文や「insert ~ on conflict」構文を利用する。
サブクエリで同じ条件のデータが複数になった場合
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 (
select
product_id
, quantity
, 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句で指定した項目でユニークになるよう注意すること。
参考URL
-
SQLite 公式サイト(英語)
https://www.sqlite.org/index.html -
2.2 UPDATE FROM (英語)
公式のUPDATE~FROMに関するドキュメント
https://www.sqlite.org/lang_update.html#upfrom
- あさはか備忘録: SQLite3 Selectしたデータを他のテーブルに挿入 https://sfnovicenotes.blogspot.com/2019/07/sqlite3-select.html
- あさはか備忘録: SQLite3 SelectしたデータでUpdateする https://sfnovicenotes.blogspot.com/2019/08/sqlite3-selectupdate.html