本文へスキップ
BecomeCoder

SQL テーブル設計 (DDL)コース · 第5章 テーブルの先へ · レッスン16

ビュー ― 保存された SELECT に名前を付ける

ブラウザで完結

導入

同じ SELECT を何度も書いていると、だんだん面倒になってきます。「東京に住んでいる人の一覧」「会員ごとの購入金額」――こういうよく使う問い合わせに名前を付けて保存できたら便利です。それが ビュー(View) です。ビューは「保存された SELECT 文」で、まるでテーブルのように SELECT できます。

説明

ビューは CREATE VIEW ビュー名 AS SELECT ...; で作ります。中身はただの SELECT 文です。

CREATE VIEW tokyo_users AS
  SELECT id, name, age FROM users WHERE city = '東京';

作ったあとは、テーブルと同じように名前で呼び出せます。

SELECT * FROM tokyo_users;

ビューはデータそのものを持ちません。呼び出すたびに、裏側で元の SELECT が実行され、そのときの最新のテーブルの中身が返ります。元テーブル(users)が変われば、ビューの結果も自動で変わります。

flowchart LR
  U["users テーブル<br/>実データを持つ"] -->|"裏で SELECT を実行"| V["tokyo_users ビュー<br/>実データを持たない“窓”"]
  V -->|"SELECT * FROM tokyo_users"| R["東京の人だけの結果<br/>(常に最新)"]

ビューの真価は、複雑な JOIN や集計に名前を付けて隠せることです(JOIN や集計は姉妹コース「SQL データ操作(DML)」で学びます)。たとえば「会員ごとの購入金額」を求める長いクエリを、user_totals という名前にしまってみましょう。

CREATE VIEW user_totals AS
  SELECT u.name, SUM(oi.quantity * p.price) AS total
  FROM order_items oi
  JOIN orders   o ON oi.order_id   = o.id
  JOIN users    u ON o.user_id     = u.id
  JOIN products p ON oi.product_id = p.id
  GROUP BY u.name;

SELECT * FROM user_totals ORDER BY total DESC;

4表の JOIN を毎回書かずに、SELECT * FROM user_totals だけで売上ランキングが得られます。不要になったビューは DROP VIEW ビュー名; で消せます。ビューを消しても、元のテーブルには影響しません(消えるのは「保存された SELECT」だけ)。

やってみよう

初期表示の CREATE VIEW tokyo_users ... を実行しましょう(「返却行なし」でOK)。続けて SELECT * FROM tokyo_users; で東京の人だけが並ぶことを確認してください。さらに上の user_totals ビューも作って SELECT * FROM user_totals ORDER BY total DESC; を試すと、「保存した集計」がそのまま呼び出せることが分かります。

演習

products から価格が1万円以上の商品だけを取り出すビュー expensive_products を作ってください。列は idnameprice の3つにします。

ヒント1を見る

CREATE VIEW expensive_products AS SELECT ... FROM products WHERE price >= 10000; の形です。

ヒント2を見る

CREATE VIEW expensive_products AS SELECT id, name, price FROM products WHERE price >= 10000;(作成後 SELECT * FROM expensive_products; で確認)

実際に動かしてみよう

下のエディタにクエリを書いて「実行」を押すと、ブラウザ内のSQLiteで結果が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう。

SQL — ブラウザ内で実行(SQLite)

ブラウザ内でSQLを動かす環境(SQLite)を読み込みます(初回のみ一瞬)。
スクロールして表示された時点でも自動で読み込まれます。