10. MS SQL Derived Table

 


🚀 導出テーブル(Derived Table)

今回学ぶ「導出テーブル(Derived Table)」は、とても重要な機能です。

これは、SQLクエリの途中で一時的なテーブルをその場で作ってしまう魔法のようなテクニックです!


🧐 第1章:導出テーブルとは何か?

1-1. 導出テーブルの正体

導出テーブルとは、FROM句JOIN句の中で、SELECT文を使って定義される一時的なクエリの結果のことです。

簡単に言えば、「()の中に書かれたSELECTの結果」を、一時的に一つのテーブルとして扱います。

役割クエリの途中で一時的なテーブルを作り、それをメインのクエリで利用する。
場所FROM句 または JOIN句テーブル名を書く場所

1-2. 構文と必須ルール

導出テーブルを使うには、次の二つの絶対ルールを守る必要があります。

  1. 必ず括弧 ( ) で囲む:一時的なクエリ全体を括弧で包みます。

  2. 必ず別名(エイリアス)を付ける:括弧の直後に AS [別名] を指定する必要があります。(例: AS PersonName

SELECT
    * -- ① 外部クエリ(最終的に実行したいクエリ)
FROM
    (
        SELECT BusinessEntityID, FirstName, LastName
        FROM Person.Person
    ) AS PersonName; -- ② 導出テーブル(一時テーブル)と**必須の別名**

💡 第2章:導出テーブルを使うメリット

導出テーブルを使う最大のメリットは、「関数を何度も評価する手間を省き、クエリを整理できる」ことです。

2-1. 関数評価の重複を防ぐ(性能向上)

例えば、「注文年(YEAR(OrderDate))」でデータを絞り込み、さらにグループ化したい場合を考えます。

【非推奨(関数を複数回評価)】

-- ❌ YEAR(OrderDate)という関数をWHEREとGROUP BYで2回も評価している
SELECT YEAR(OrderDate) AS OrderYear, COUNT(*)
FROM Sales.SalesOrderHeader
WHERE YEAR(OrderDate) = 2006
GROUP BY YEAR(OrderDate);

【導出テーブルで解決】

導出テーブル内で一度だけYEAR()関数を実行し、その結果(OrderYearという列名)を外部クエリで再利用します。

SELECT
    OrderYear,
    COUNT(*) AS SalesCount
FROM
    (
        -- ★ 内部クエリ:YEAR関数はここで一度だけ評価される
        SELECT YEAR(OrderDate) AS OrderYear, SalesOrderID
        FROM Sales.SalesOrderHeader
    ) AS SalesDetails -- 必須の別名
WHERE
    OrderYear = 2006 -- OrderYearという列名を使ってシンプルに絞り込める
GROUP BY
    OrderYear;       -- OrderYearという列名を使ってシンプルにグループ化できる

2-2. 複数の集計結果を結合する

導出テーブルは、JOIN句の中でも活躍します。複雑な集計や加工を別々に行い、その結果を後から結合したい場合に非常に便利です。

【応用例】

  1. 導出テーブルA:売上テーブルから「年ごとの合計売上」を計算する。

  2. 導出テーブルB:人事テーブルから「年ごとの採用人数」を計算する。

  3. 外部クエリ:AとBを「年」でJOINして、年ごとの売上と採用人数を並べて表示する。

このように、複雑な問題を小さなブロックに分けて処理できるため、クエリが読みやすく、管理しやすくなります。


🔗 第3章:導出テーブルの応用テクニック

3-1. 導出テーブルのネスト(入れ子)

関数のネストと同様に、導出テーブルもネスト(入れ子)にできます。

( SELECT ... FROM ( SELECT ... FROM TableX ) AS InnerTable ) AS OuterTable

SQLは、この場合も最も内側のテーブルから順番に評価し、その結果を外側のテーブルの入力として使います。

3-2. JOIN句での利用

JOINを使う場所(テーブル名を指定する場所)であれば、FROM句と同様に導出テーブルを使えます。

SELECT ...
FROM
    TableA
INNER JOIN
    (
        -- 💡 JOIN相手も導出テーブルにできる
        SELECT ID, COUNT(*) AS Cnt FROM TableB GROUP BY ID
    ) AS B_Count ON TableA.ID = B_Count.ID

導出テーブルは、一時的な「作業台」のようなものです。この技術を身につければ、より複雑なビジネス要件にも対応できる、強力で整理されたSQLを書くことができるようになります!