8.

インラインビュー

編集

本稿は SQL のインラインビューに関する記事です。インラインビューは Oracle 用語として広まっていますが、現在ではほぼすべての RDBMS で同じ概念がサポートされています。

インラインビューとは?

インラインビュー (Inline View) とは、FROM 句に書く SELECT 文 (副問い合わせ) のことです。あらかじめ作成しておく永続的なビュー (CREATE VIEW) ではなく、その SQL の中でその場限りに使い捨てる仮想テーブルとして動作します。

SELECT u.name, t.cnt
  FROM users u
 INNER JOIN (
        SELECT user_id, COUNT(*) AS cnt
          FROM orders
         GROUP BY user_id
      ) t   -- ← この部分がインラインビュー
    ON u.id = t.user_id
 WHERE t.cnt > 5;

インラインビューを使う典型的なケース

ユースケース
集計してから結合ユーザ別注文件数を計算 → users と JOIN
絞り込み済みの「小さなテーブル」を用意過去 30 日の対象データのみで JOIN し性能改善
同じ複雑なサブクエリを別名で扱うFROM (...) AS top10 として読みやすく
ウィンドウ関数の結果を外側で参照SELECT * FROM (SELECT ..., ROW_NUMBER() OVER (...) rn FROM t) WHERE rn = 1
UNION を1つの集合として扱うFROM (SELECT ... UNION ALL SELECT ...) AS x

類似機能との違い

機能定義位置寿命備考
インラインビューFROM句内のサブクエリそのクエリのみその場限り。命名は別名 (AS x)
CTE (WITH句)クエリ先頭の WITH name AS (...)そのクエリのみ名前付きでクエリ内で複数回参照可
ビュー (VIEW)CREATE VIEW永続スキーマに登録される
マテリアライズドビューCREATE MATERIALIZED VIEW永続+実体化結果を物理保存。Oracle / PostgreSQL 等で利用
一時テーブルCREATE TEMPORARY TABLEセッション内明示的にデータを保持
スカラサブクエリSELECT 句や WHERE 句その場限り結果は 1 行 1 列のみ

CTE (WITH句) との書き換え例

同じ処理はインラインビューでも CTE でも書けます。複雑になるほど CTE のほうが見やすいことが多いです。

-- CTE 版
WITH order_cnt AS (
  SELECT user_id, COUNT(*) AS cnt
    FROM orders
  GROUP BY user_id
)
SELECT u.name, oc.cnt
  FROM users u
  JOIN order_cnt oc ON u.id = oc.user_id
 WHERE oc.cnt > 5;

パフォーマンス上のポイント

  • インラインビュー内で不要な列を取らないSELECT * は避けて必要列のみ
  • WHERE で先に絞ると、外側の JOIN が高速になる
  • 同じ集計を外側で何度も呼ぶような書き方ならCTE / 一時テーブルを検討
  • EXPLAIN実行計画を確認し、フルスキャンになっていないかチェック
  • Oracle の場合、インラインビューに WITH ... AS ヒントや マテリアライズドビューが効くケースがある

注意点

  • 多くの RDBMS でインラインビューには必ず別名 (AS xx) を付ける必要がある
  • インラインビュー内でORDER BY は省略可能。最終結果の並びは外側の ORDER BY で決める
  • ネストが深くなりすぎると可読性が落ちる。3階層以上は CTE への書き換えを検討
  • RDBMS により対応 SQL 機能が異なる (ウィンドウ関数の対応バージョン等)。サポート状況を確認

関連

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. SELECT文
  2. INSERT文
  3. UPDATE文
  4. DELETE文
  5. WHERE句
  6. JOIN句
  7. 集合演算子
  8. インラインビュー
  9. 副問い合わせ