documents:proglang:sql:sql-0010
差分
このページの2つのバージョン間の差分を表示します。
| 両方とも前のリビジョン前のリビジョン | |||
| documents:proglang:sql:sql-0010 [2026/05/08 12:19] – ↷ documents:database:sql-0010 から documents:proglang:sql:sql-0010 へページを移動しました。 k896951 | documents:proglang:sql:sql-0010 [2026/05/16 11:36] (現在) – [SQLで不足レコードを補うクエリの発行] k896951 | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| + | ====== 005.SQLで不足レコードを補うクエリの発行 ====== | ||
| + | |||
| + | 2017年11月16日\\ | ||
| + | 自分用メモ。 | ||
| + | |||
| + | ===== 処理対象データ ===== | ||
| + | |||
| + | PostgreSQLに以下のデータがある。 | ||
| + | |||
| + | <code sql> | ||
| + | $ psql -h 192.168.1.30 kamonohashi kamo | ||
| + | psql (9.6.5) | ||
| + | " | ||
| + | |||
| + | kamonohashi=> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (6 行) | ||
| + | |||
| + | kamonohashi=> | ||
| + | </ | ||
| + | |||
| + | これにレコードを補い、以下のように各日で必ずITEM1~ITEM3のレコードが現れるようにしたい。 | ||
| + | |||
| + | <code sql> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | |||
| + | ===== 方法1:3回のクエリ発行 ===== | ||
| + | |||
| + | 単純に、ITEM1~ITEM3のいずれかの記録がされた日付に、記録がないアイテムのレコードを追加する。 | ||
| + | |||
| + | 例えばITEM1の不足レコードを追加するには以下のクエリとなる。 | ||
| + | <code sql> | ||
| + | with t as ( | ||
| + | select distinct day from salelog | ||
| + | ) | ||
| + | insert into salelog | ||
| + | select t.day, ' | ||
| + | where not exists(select * from salelog m where m.day=t.day and m.item=' | ||
| + | ; | ||
| + | </ | ||
| + | |||
| + | 実行してみる。 | ||
| + | |||
| + | <code sql> | ||
| + | kamonohashi=> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | INSERT 0 1 | ||
| + | kamonohashi=> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (7 行) | ||
| + | |||
| + | kamonohashi=> | ||
| + | </ | ||
| + | |||
| + | | ||
| + | |||
| + | 続けて ITEM2,ITEM3 のクエリも実行してみる。 | ||
| + | |||
| + | <code sql> | ||
| + | kamonohashi=> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | INSERT 0 2 | ||
| + | kamonohashi=> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | INSERT 0 3 | ||
| + | kamonohashi=> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (12 行) | ||
| + | </ | ||
| + | |||
| + | 3つのクエリを実行し、6レコードが追加された。 | ||
| + | 見易くソートをかけると、期待通りの結果であることがわかる。 | ||
| + | |||
| + | <code sql> | ||
| + | kamonohashi=> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (12 行) | ||
| + | |||
| + | kamonohashi=> | ||
| + | </ | ||
| + | |||
| + | ===== 方法2:1回のクエリ発行 ===== | ||
| + | |||
| + | 事前に以下のテーブルを用意する。 | ||
| + | <code sql> | ||
| + | kamonohashi=> | ||
| + | item | ||
| + | ------- | ||
| + | ITEM1 | ||
| + | ITEM2 | ||
| + | ITEM3 | ||
| + | (3 行) | ||
| + | |||
| + | kamonohashi=> | ||
| + | </ | ||
| + | |||
| + | このテーブル itemlist を組み合わせるクエリは以下となる。 | ||
| + | <code sql> | ||
| + | with t as ( | ||
| + | select d.day, m.item | ||
| + | from ( select distinct day from salelog) d | ||
| + | cross join itemlist m | ||
| + | ) | ||
| + | insert into salelog | ||
| + | select t.day, t.item, 0 from t | ||
| + | where not exists(select * from salelog m where m.day=t.day and m.item=t.item) | ||
| + | ; | ||
| + | </ | ||
| + | |||
| + | 実行結果は期待通りになっている。 | ||
| + | |||
| + | <code sql> | ||
| + | kamonohashi=> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi(> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | kamonohashi-> | ||
| + | INSERT 0 6 | ||
| + | kamonohashi=> | ||
| + | | ||
| + | ---------------------+-------+----- | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | (12 行) | ||
| + | |||
| + | kamonohashi=> | ||
| + | </ | ||
| + | |||
| + | ===== 説明 ===== | ||
| + | |||
| + | キー項目でINSERT先の既存レコードの存在を確認し、レコードが存在しないならそのキー項目を持つレコードを追加している。 | ||
| + | この例では、項目day、項目item、が該当する。 | ||
| + | |||
| + | レコードの存在有無は EXISTS()関数で確認できる。 | ||
| + | レコードがあれば EXISTS(…)の戻り値はTRUEとなる。追加先のテーブル salelog 内にキーで示すレコードが存在しないならEXISTS(…)の結果はFALSEになるので、NOT EXISTS(…)で条件が成立する。\\ | ||
| + | ※EXISTS(…)=TRUE時はすでにそのキーのレコードがあるので追加してはいけない | ||
| + | |||
| + | EXISTS()関数内のクエリで使うキー項目を持つレコードセットが t になる。 | ||
| + | |||
| + | 方法2ではレコードセット t を作るためにテーブル itemlist を使ったが、このテーブルも置き換えできる。例えば | ||
| + | <code sql> | ||
| + | with t as ( | ||
| + | select d.day, m.item | ||
| + | from ( select distinct day from salelog) d | ||
| + | cross join ( select distinct item from salelog) m | ||
| + | ) | ||
| + | insert into salelog | ||
| + | select t.day, t.item, 0 from t | ||
| + | where not exists(select * from salelog m where m.day=t.day and m.item=t.item) | ||
| + | ; | ||
| + | </ | ||
| + | |||
| + | でもいい。 | ||
| + | |||
| + | また、レコードセット t は、WITHを使わずサブクエリにしても構わない。 | ||
| + | <code sql> | ||
| + | insert into salelog | ||
| + | select t.day, t.item, 0 | ||
| + | from ( | ||
| + | select d.day, m.item | ||
| + | from ( select distinct day from salelog) d | ||
| + | cross join ( select distinct item from salelog) m | ||
| + | ) t | ||
| + | where not exists(select * from salelog m where m.day=t.day and m.item=t.item) | ||
| + | ; | ||
| + | </ | ||
| + | |||
| + | {{tag> database SQL 不足レコード補填 PostgreSQL 技術資料}} | ||
documents/proglang/sql/sql-0010.txt · 最終更新: by k896951
