SQLの絵本 - 5章 基本操作(2)

SQLの絵本―データベースがみるみるわかる9つの扉のメモ。

概要

  • UPDATE/DELETEによるデータの更新
  • SELECT文の中のSELECT文、サブクエリ

INSERT文

列名を省略して登録

INSERT文では列の順にVALUESを指定すれば列名を省略できる。

INSERT INTO tbl_tea VALUES (2, '紅茶', 850);
特定の列にのみ値を登録する

一部の列にのみ値を登録した場合、登録しなかった列にはテーブル作成時の制約に基づいた値が設定される。特に制約を設定していなければNULLが挿入される。

SELECT文により登録するデータを指定する

SELECT文で選択した他のテーブルの列をINSERT文に与えることでそのまま列として登録できる。

INSERT INTO tbl_petlist (id, name) SELECT no, name FROM tbl_cat;

UPDATE文

UPDATE文は登録されている値の更新を行う。

UPDATE tbl_lunch SET price = 760 WHERE code = 2;

SETに続いて更新内容を、WHEREに続いて更新する行を指定する条件を設定する。WHERE句を省略した場合全ての行の値が変更される。
複数の値を更新する場合はSETに続く更新内容をカンマで区切って指定する。

DELETE文

DELETE文は登録されているデータを削除する

DELETE FROM tbl_tel WHERE name = '花田';

FROMに続いて対象のテーブルを、WHERE句に続いて削除する行を指定する条件を設定する。WHERE句を省略するとテーブルのデータ全てが削除される。

サブクエリ

WHERE句でサブクエリを使用

SELECT文の抽出条件にSELECT文を用いることができる。このときネストされたSELECT文をサブクエリ(副問い合わせ)と呼ぶ。

SELECT * FROM tbl_cake -- 平均値を求めてWHERE句に利用
      WHERE price >= (SELECT AVG(price) FROM tbl_cake);
HAVING句でサブクエリを使用
SELECT code, MIN(arrival) FROM tbl_stock GROUP BY code
       HAVING MIN(arrival) < (SELECT AVG(shipment) FROM tbl_stock);

上の文の処理は次のようになる。

  1. サブクエリの実行: shipmentの平均値を算出
  2. メインクエリの実行: codeを基準にグループ化し、arrivalの最小値がshipmentの平均値より小さいグループのデータのみを表示
FROM句でサブクエリを使用

RDBMSによってはFROM句にサブクエリを使用できる。

SELECT MIN(price) FROM
   (SELECT * FROM tbl_cake WHERE price >= 250) AS c_price;

FROM句にサブクエリを使用すると、サブクエリによって作成されたビュー(インラインビュー)に対して処理が行われる。

INSERT、UPDATE、DELTEでのサブクエリの使用

例ではWHERE句における条件を作成する目的でサブクエリを利用している。
point1とpoint2の和が平均より大きいデータのみを抜き出して新しいテーブルに追加。

INSERT INTO tbl_advance SELECT * FROM tbl_results
       WHERE point1 + point2 > (SELECT AVG(point1 + point2) FROM tbl_results);

overtimeとtravelの和がovertimeの最大値より小さいデータのみtotalを計算して挿入(MySQLのサブクエリではテーブルの更新と参照が同時にできないので下記コードはエラーとなる)。

UPDATE tbl_allowance SET total = (overtime + travel)
        WHERE overtime + travel < (SELECT MAX(overtime) FROM tbl_allowance);

overtime40000以上のデータのtravelの平均値よりtravelの値が大きいデータを削除(上と同じ理由によりMySQLでは動かない)。

DELETE FROM tbl_allowance WHERE travel > (SELECT AVG(travel)
       FROM tbl_allowance WHERE overtime >= 40000);