Q1ビュー(VIEW)の説明として正しいものはどれですか。
ビュー(VIEW) — 定義と用途
この記事は、基礎から複雑なSQL,SQLチューニングまでSQLの実践的なスキルを1からマスターする「SQL入門講座の一部」です。
employeeとdepartmentを結合したemp_dept、給与帯emp_tier、社員別売上emp_salesをCREATE VIEWで定義し、再利用・権限・抽象化の3つの用途と、もとのテーブル更新がビューにすぐ反映される振る舞いを確かめます。
本記事で使うデータ — employee / department / sales
ビュー(VIEW)は、SELECT文に名前を付けて保存し、その名前をテーブルのように参照できる仕組みです。
テーブルと違ってデータ自体は持たず、参照されるたびに保存されたSELECTが実行されます。
CREATE VIEW — 複雑なクエリに名前を付ける
ビューはCREATE VIEW ビュー名 AS SELECT ...;で定義します。
定義した後はSELECT * FROM ビュー名と書くだけで、保存されたSELECTが実行され、その結果が返ります。
実体のデータを持たない保存されたクエリなので、もとのテーブルが更新されると、ビューを参照した結果も最新の状態になります。
不要になったビューはDROP VIEW ビュー名;で削除します。
同じ名前のビューを作り直したいときはDROP VIEW IF EXISTS ビュー名;を先に実行してからCREATE VIEWすると、再実行しても失敗しません。
SELECT文だけを保存します。ビューを参照すると、その都度もとのテーブルに対して保存済みのSELECTが実行されます。-- 部署ごとの人数を出すクエリにビューとして名前を付ける例
DROP VIEW IF EXISTS dept_headcount;
CREATE VIEW dept_headcount AS
SELECT d.dept_name, COUNT(e.emp_id) AS headcount
FROM department d
LEFT JOIN employee e ON e.dept_id = d.dept_id
GROUP BY d.dept_name;
-- 定義後はテーブルのように参照できる
SELECT dept_name, headcount FROM dept_headcount
ORDER BY headcount DESC;
-- 不要になったら削除
DROP VIEW dept_headcount;
ビューの用途 — 再利用・権限・抽象化
ビューを使う主な目的は 3 つあります。
再利用: よく使う結合や集計を 1 つの名前にまとめ、同じクエリを何度も書かずに済ませます。
権限: テーブルの一部の列・行だけを見せるビューを作り、利用者にはテーブルそのものではなくビューだけにアクセスを許せます(給与の高い列を隠す、自分の部署の行だけ見せる、など)。
抽象化: 利用側はビューの内部構造(どのテーブルをどう結合しているか)を知らなくても、ビュー名と返る列だけ知っていれば使えます。
-- ① 抽象化: 入社年でラベル付けしたビュー(利用側は式を意識しない)
DROP VIEW IF EXISTS emp_cohort;
CREATE VIEW emp_cohort AS
SELECT name, hired_on,
CASE
WHEN hired_on < '2018-01-01' THEN 'Veteran'
WHEN hired_on < '2021-01-01' THEN 'Mid'
ELSE 'Recent'
END AS cohort
FROM employee;
SELECT cohort, COUNT(*) AS cnt
FROM emp_cohort
GROUP BY cohort
ORDER BY cohort;
DROP VIEW emp_cohort;
-- ② 権限: 給与列を含めず公開してよい列だけのビュー
DROP VIEW IF EXISTS emp_public;
CREATE VIEW emp_public AS
SELECT emp_id, name, dept_id FROM employee;
DROP VIEW emp_public;
集計をまとめたビューで利用側を短くする
ビューには結合だけでなくGROUP BYの集計結果も保存できます。
社員ごとの売上合計のように、利用側が何度も使う集計を 1 つのビューにまとめておくと、利用側はJOINやGROUP BYを書かずに、すでに集計済みの行をSELECTするだけで済みます。
下の例ではsalesを社員ごとに集計し、employeeと結合して社員名を付けたビューを定義します。
利用側は「誰がいくら売ったか」をビュー名で参照するだけで、内部の結合と集計を意識しません。
GROUP BYをビュー側に閉じ込めると、利用側はビューからSELECTするだけで集計済みの結果を得られます。-- 部署別の売上合計に部署名を付けたビュー
DROP VIEW IF EXISTS dept_sales;
CREATE VIEW dept_sales AS
SELECT d.dept_name, SUM(s.amount) AS total
FROM sales s
JOIN employee e ON s.emp_id = e.emp_id
JOIN department d ON e.dept_id = d.dept_id
GROUP BY d.dept_name;
-- 利用側は集計済みのビューを SELECT するだけ
SELECT dept_name, total FROM dept_sales
ORDER BY total DESC;
DROP VIEW dept_sales;
理解度チェック
まずは1問ずつ答えてみましょう。
Q2ビューを使う用途として、本文で挙げられていないものはどれですか。
Q3emp_tierビューを定義したあと、もとのemployeeテーブルに新しい行を INSERT しました。ビューを定義し直さずにSELECT * FROM emp_tierを実行するとどうなりますか。