SQL総復習⑤ ビューとサブクエリ
こんにちは!
スマレジ テックファームのMichiです!
今回は『SQL総復習⑤ ビューとサブクエリ」編です。
ビュー
ビューとは?
一言でいうと、ビューとは「SELECT文を保存しているテーブル」のことです。
通常のテーブルでは、DBに格納されているデータはコンピュータ内の物理的な記憶装置に保存されます。SELECT
文でデータを検索しようとするときは、実際にこの規則装置からデータを引っ張り出して計算を行い、ユーザーへ返すという過程をたどります。
一方、ビューの場合はデータを記憶装置に保存しません。というより、どこにも保存しません。ビューが保存しているのは「SELECT文そのものです」。私たちがビューからデータを取り出そうとするときに、ビューは内部的にそのSELECT
文を実行し一時的に仮想のテーブルを作ります。
ビューの作り方
ビューを作成するにはCREATE VIEW
文を使います。
CREATE VIEW <ビュー名> (<カラム名1>, <カラム名2>, ...) AS <SELECT文>
実際に作ってみます。次のようなitems
テーブルがあると仮定します。
+----+------------+-------+----------+ | id | name | price | category | +----+------------+-------+----------+ | 1 | ベッド | 20000 | 家具 | | 2 | ノート | 100 | 文房具 | | 3 | ボールペン | 200 | 文房具 | | 4 | シャツ | 3000 | 衣類 | | 5 | ホッチキス | 500 | 文房具 | | 6 | ズボン | 4000 | 衣類 | +----+------------+-------+----------+
CREATE VIEW
文を作成します。
CREATE VIEW items_by_category (category, count_category) AS SELECT category, COUNT(*) FROM items GROUP BY category;
すると、次のようなビューが作成されます。
+------------+----------------+ | category | count_category | +------------+----------------+ | 家具 | 1 | | 衣類 | 2 | | 文房具 | 3 | +------------+----------------+
これは、CREATE VIEW
文内で指定したSELECT句SELECT category, COUNT(*) FROM items GROUP BY category;
を実行した場合と全く同じ結果となります。
このビューは通常のテーブルと同じように使用することができます。なので、結果を取り出したいときはSELECT
文を書けばOKです。
SELECT * FROM items_by_category;
ビューのメリット
ビューのメリットは大きく分けて2つあります。
ひとつめは、データを保存しないため、記憶装置の容量を節約できることです。
先ほどの例の結果を実際のテーブルとして保存する場合、当然ながらデータ分の記憶装置の保存領域を消費します。しかしながら、ビューが保存しているのはあくまでSELECT文ですので、数行のクエリ文相当の保存領域しか消費しません。
ふたつめのメリットは、頻繁に使うSELECT
文をいちいち毎回書かなくても、ビューとして保存しておくことで使いまわしがきくことです。
例に挙げたSELECT
文はごくシンプルなものですので、毎回書くことの煩わしさは少ないかもしれませんが、複雑なクエリになるほどビューによる効率化の恩恵は大きくなります。
ビューの注意点
1. ORDER BY句は使えない
ビュー定義のSELECT
文にはORDER BY
句は使えません。したがって、次のようなビュー定義はエラーとなります*1。
CREATE VIEW items_by_category (category, count_category) AS SELECT category, COUNT(*) FROM items GROUP BY category ORDER BY category;
ORDER BY
が使えない理由は、テーブルと同じくビューには行の順序が存在しないからです(テーブルの並び順はシステムで保証されない)。
逆に言えば、ORDER BY
以外の句ならば何でも書くことができます。
2. ビューに対する更新
ビューではSELECT
文の他に、INSERT
、UPDATE
、DELETE
文を使用することも一応は可能です。ただし、これらの文を使用するには「ビュー作成元のテーブルと競合しない」という制限があります。代表的な例を挙げると、以下のような条件です。
SELECT
句にDISTINCT
が含まれていないFROM
句に含まれるテーブルが一つだけであるGROUP BY
句を使用していないHAVING
句を使用していない
以上からも、INSERT
、UPDATE
、DELETE
文を使用する際には常に、ビューではなく元のテーブルを更新する方がよいと筆者は考えます。
サブクエリ
サブクエリとは?
サブクエリを一言で説明すると、「使い捨てのビューです」。
ビューではSELECT
文を記憶領域に保存していましたが、それに対してサブクエリは記憶領域には保存せず、SELECT
文をそのままFROM
句に持ち込みます。
サブクエリの作り方
先ほどビューを使って出力した結果を、サブクエリを使用して出してみましょう。
SELECT category, count_category FROM ( SELECT category, COUNT(*) AS count_category FROM items GROUP BY category ) AS items_by_category;
先ほどのビューを作成した際に作成したSELECT
文を、そのままFROM
句に挿入しています。結果は次のようになり、先ほどのビューを作成したときの結果と全く同じです。
+------------+----------------+ | category | count_category | +------------+----------------+ | 家具 | 1 | | 衣類 | 2 | | 文房具 | 3 | +------------+----------------+
サブクエリのメリット
ビューと同じくデータを保存しないため、記憶装置の容量を節約できることが挙げられます。
ただし、サブクエリは使い捨てで保存領域を消費しないので、その場で一度きりしか使用しないようなSELECT
文の場合はビューよりも優れているといえます。
サブクエリの注意点
1. 実行順はサブクエリ → 通常クエリ
サブクエリを書いた場合は、通常クエリよりも先にサブクエリが実行されます(上の例では、先にFROM
句を実行しないと、どこからSELECT
したらよいのか分かりませんね)。実際のSQLの書き順とは異なるので注意しましょう。
2. 最後の「AS <サブクエリ名>」は必須
先ほどの例では、サブクエリの最後にAS items_by_category
と付けることで、このサブクエリ自体に名前を付けています。これは使い捨ての名前なので、ビューのように記憶装置に保存されることはなく、SELECT
文の実行終了後には消えてなくなります。
と書くと、「じゃあ、別名付けなくてもいいんじゃね?」と思うかもしれませんが、これはサブクエリのルールとして決まっているものなので、別名は絶対に付けなければなりません。尚、別名を付けるときはAS
キーワードを使用しますが、このAS
は省略することが可能です。
まとめ
今回はビューとサブクエリについて解説しました。
ここまでお読みいただきありがとうございました。
*1:PostgreSQLだけはエラーとならない