【SQL】INSERT:他のテーブルからコピーする

  • #SQL

VALUES句でデータを指定する以外に、「他のテーブルから選択する」という方法もある

/* データ挿入先のテーブルを作る */
CREATE TABLE ShohinCopy
(
  shohin_id CHAR(4) NOT NULL,
  shohin_mei VARCHAR(100) NOT NULL,
  shohin_bunrui VARCHAR(32) NOT NULL,
  hanbai_tanka INTEGER DEFAULT 0,
  shiire_tanka INTEGER,
  torokubi DATE,
  PRIMARY KEY(shohin_id)
);
  • ここで作成したテーブルの定義は、これまで学習に使ったテーブルと同じもの
  • 新たに作成したテーブル「ShohinCopy」に、
    テーブル「Shohin」の値をそのままINSERTする
/* 「Shohinテーブル」のデータを
	 「ShohinCopy」へコピー */
	
INSERT INTO ShohinCopy (
  shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi
) SELECT
  shohin_id, shohin_mei, shohin_bunrui, hanbai_tanka, shiire_tanka, torokubi
  FROM Shohin;

「Shohin」テーブルと同じデータの「ShohinCopy」テーブルができる

SELECT * FROM Shohin;

 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi  
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 | 
 0004      | 包丁           | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋         | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク       | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね     | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11
 
 
SELECT * FROM ShohinCopy;

 shohin_id |   shohin_mei   | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi  
-----------+----------------+---------------+--------------+--------------+------------
 0001      | Tシャツ        | 衣服          |         1000 |          500 | 2009-09-20
 0002      | 穴あけパンチ   | 事務用品      |          500 |          320 | 2009-09-11
 0003      | カッターシャツ | 衣服          |         4000 |         2800 | 
 0004      | 包丁           | キッチン用品  |         3000 |         2800 | 2009-09-20
 0005      | 圧力鍋         | キッチン用品  |         6800 |         5000 | 2009-01-15
 0006      | フォーク       | キッチン用品  |          500 |              | 2009-09-20
 0007      | おろしがね     | キッチン用品  |          880 |          790 | 2008-04-28
 0008      | ボールペン     | 事務用品      |          100 |              | 2009-11-11

データのバックアップ(予備)をとるときに使える!


INSERT文にWHERE句やGROUP BY句も使える

テーブル同士でデータをやり取りできる

/* 商品分類ごとにまとめたテーブルを作る */
CREATE TABLE ShohinBunrui
(
  shohin_bunrui VARCHAR(32) NOT NULL,
  sum_hanbai_tanka INTEGER,
  sum_shiire_tanka INTEGER,
  PRIMARY KEY(shohin_bunrui)
);

このテーブルでは、商品分類ごとに以下を保持する

  • 販売単価の合計(sum_hanbai_tanka)
  • 仕入単価の合計(sum_shiire_tanka)

Shohinテーブルからデータを集約して挿入する

/* データを集約して挿入 */
INSERT INTO ShohinBunrui
(
  shohin_bunrui, sum_hanbai_tanka, sum_shiire_tanka
) SELECT
  shohin_bunrui, SUM(hanbai_tanka), SUM(shiire_tanka)
  FROM Shohin
  GROUP BY shohin_bunrui;
  
  
 shohin_bunrui | sum_hanbai_tanka | sum_shiire_tanka 
---------------+------------------+------------------
 キッチン用品  |            11180 |             8590
 衣服          |             5000 |             3300
 事務用品      |              600 |              320

【検証】データを削除したら?

  1. 集約の元になったテーブル「Shohin」から1行削除する
  2. 「ShohinBunrui」テーブルの合計値はどうなる?
/* 商品ID'0005'のデータを確認 */
SELECT * FROM Shohin WHERE shohin_id = '0005'; 

 shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi  
-----------+------------+---------------+--------------+--------------+------------
 0005      | 圧力鍋     | キッチン用品  |         6800 |         5000 | 2009-01-15
/* 商品ID'0005'を1行削除する */
DELETE FROM Shohin WHERE shohin_id = '0005';

 shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka | torokubi 
-----------+------------+---------------+--------------+--------------+----------

「ShohinBunrui」テーブルの合計値は変わっているのか?

/* 商品ID'0005'の削除後 */
SELECT * FROM ShohinBunrui;

/* 合計値は削除前と同じ */
 shohin_bunrui | sum_hanbai_tanka | sum_shiire_tanka 
---------------+------------------+------------------
 キッチン用品  |            11180 |             8590
 衣服          |             5000 |             3300
 事務用品      |              600 |              320

【結論】行を削除してもデータは変わらなかった → INSERT文を実行したときの値が保持される


※商品テーブルは元に戻しました

INSERT INTO Shohin VALUES (
  '0005', '圧力鍋', 'キッチン用品', 6800, 5000, '2009-01-15'
);

SELECT * FROM Shohin WHERE shohin_id = '0005'; 

/* 元通り */
 shohin_id | shohin_mei | shohin_bunrui | hanbai_tanka | shiire_tanka |  torokubi  
-----------+------------+---------------+--------------+--------------+------------
 0005      | 圧力鍋     | キッチン用品  |         6800 |         5000 | 2009-01-15

INSERTのまとめ:データの登録とNOT NULL/デフォルト値/この記事

参考書籍:ミック『SQL 第2版 ゼロからはじめるデータベース操作』(翔泳社)