WITH [テーブル名] AS( SELECT ....)
という記述があるのですが、これは何でしょう?一時テーブルっぽく見えます。
select id, model, name, category, price FROM products WHERE price > AVG(price)
WITH [テーブル名] AS( SELECT ....)
という記述があるのですが、これは何でしょう?一時テーブルっぽく見えます。
共通テーブル式 Common Table Expression(CTE)について紹介します。
WITH ~ AS (...)
という形で定義される、一時的な名前付きのクエリ結果です。
見た目は一時テーブルに似ていますが、実際にはメモリやtempdbに物理的なテーブルを作成するわけではありません。
項目 | 内容 |
---|---|
名前 | 一時的なクエリ結果に対して別名(例: Duplicates)をつけられる |
対象 | 同一クエリ内でのみ有効(クエリ終了後に消える) |
用途 | ウィンドウ関数の処理、階層構造の展開、読みやすさ向上など |
パフォーマンス | 実体のない「論理的なビュー」として扱われるため、複数回参照すると都度評価されることがある(=複数回呼び出しは注意) |
書き換え可能 | INSERT INTO, UPDATE, DELETE と組み合わせて使える(制限あり) |
WITH [CTE名] AS (
[クエリ]
)
[クエリ]
id | model | name | category | price |
---|---|---|---|---|
1 | C-XM01 | モーダンチェア | チェア | 56000 |
2 | X-XD05 | ラージデスク | テーブル | 87000 |
3 | A-DA40 | ラウンドダイニングチェア | チェア | 28000 |
4 | O-XX100 | ナチュラルオフィス | チェア | 13800 |
5 | R-D400 | ラウンドダイニングテーブル | テーブル | 128000 |
6 | R7000 | ウッドキャビネット | その他 | 32000 |
INSERT INTO products (id, model, name, category, price) VALUES
(1, 'C-XM01', 'モーダンチェア', 'チェア', 56000),
(2, 'X-XD05', 'ラージデスク', 'テーブル', 87000),
(3, 'A-DA40', 'ラウンドダイニングチェア', 'チェア', 28000),
(4, 'O-XX100', 'ナチュラルオフィス', 'チェア', 13800),
(5, 'R-D400', 'ラウンドダイニングテーブル', 'テーブル', 128000),
(6, 'R7000', 'ウッドキャビネット', 'その他', 32000);
上記のテーブルでpriceの平均値より高いpriceの値を持つレコードを列挙する場合の例です。
今回はサブクエリではなく、CTEを利用して実行します。以下のSQLを記述します。
WHERE句でAVG(price)
を記述するとエラーになるため、先にpriceの平均値を計算して、CTEに挿入しておき、後半のクエリでCROSS JOINして priceの平均値を参照する動作になります。
WITH Average AS (
SELECT AVG(price) as ap FROM products
)
SELECT productsBV.* FROM products CROSS JOIN Average WHERE price > Average.ap
select id, model, name, category, price FROM products WHERE price > AVG(price)
以下の結果となります。
id | model | name | category | price |
---|---|---|---|---|
2 | X-XD05 | ラージデスク | テーブル | 87000 |
5 | R-D400 | ラウンドダイニングテーブル | テーブル | 128000 |
こちらの記事を参照してください。