0Pricing
SQL Academy · レッスン

共通テーブル式(WITH)

ネストしたクエリを読みやすいWITH句に整理し、CTEを連結し、PostgreSQL 12以降のマテリアライズ規則を学びます。

「共通テーブル式(WITH)」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

CTEとは

共通テーブル式(CTE)は、WITHで定義する名前付きサブクエリです。

WITH paid_orders AS (
  SELECT * FROM orders WHERE status = 'paid'
)
SELECT user_id, COUNT(*)
FROM paid_orders
GROUP BY user_id;

CTEを使う理由

大きなメリットは3つあります。

  • 可読性 — 200行のクエリを名前付きの手順に分割できます
  • 再利用 — 同じ中間結果を複数回参照できます
  • 再帰 — 再帰クエリをサポートするのはCTEだけです(次のレッスンで扱います)

CTEの連結

1つのWITHで複数のCTEを定義し、次のCTEで前のCTEを使用できます。

WITH last_30 AS (
  SELECT * FROM orders WHERE created_at >= NOW() - INTERVAL '30 days'
),
per_user AS (
  SELECT user_id, SUM(total) AS revenue FROM last_30 GROUP BY user_id
)
SELECT u.email, p.revenue
FROM users u
JOIN per_user p ON p.user_id = u.id
ORDER BY p.revenue DESC LIMIT 20;

CTEの再利用

同じ中間結果を2回使用する場合、CTEにすると意図が明確になります。

WITH recent_users AS (
  SELECT id FROM users WHERE created_at >= NOW() - INTERVAL '7 days'
)
SELECT 'new orders'  AS metric, COUNT(*) FROM orders
  WHERE user_id IN (SELECT id FROM recent_users)
UNION ALL
SELECT 'new revenue', SUM(total) FROM orders
  WHERE user_id IN (SELECT id FROM recent_users);

CTEのマテリアライズ(PostgreSQL ≤ 11)

古いPGバージョンでは、CTEの出力が常にマテリアライズされ、プランナーの最適化を妨げる境界になっていました。PG 12以降では、特に指定しない限り、プランナーはデフォルトでCTEをインライン化します。

-- Force the old materialise behaviour (rarely needed):
WITH x AS MATERIALIZED (SELECT ...) ...

-- Force inlining (default):
WITH x AS NOT MATERIALIZED (SELECT ...) ...

データ変更CTE

CTEではINSERT、UPDATE、DELETEも使用できます。行をテーブル間でアトミックに移動する場合に便利です。

WITH moved AS (
  DELETE FROM orders WHERE status = 'archived' RETURNING *
)
INSERT INTO orders_archive SELECT * FROM moved;

DMLでのCTE

「検索して処理する」操作には、RETURNINGとWITHを組み合わせます。

WITH cancelled AS (
  UPDATE orders SET status = 'cancelled'
  WHERE created_at < NOW() - INTERVAL '14 days'
    AND status = 'pending'
  RETURNING id
)
INSERT INTO audit_log (event, order_id)
SELECT 'auto-cancel', id FROM cancelled;

実行順序

データ変更CTEは、同じスナップショット内で独立して実行されます。各ステートメントは、すべての変更が始まる前の状態を参照します。意外に思える動作ですが、予測可能です。

CTE・サブクエリ・ビューの比較

比較すると、次のようになります。

  • サブクエリ — クエリ内に直接定義し、1回だけ使用します
  • CTE — 名前付きで、クエリ内で複数回使用できます。クエリの終了後はなくなります
  • ビュー — 名前付きで永続化され、複数のクエリから再利用できます

CTEの使い過ぎに注意

何でもCTEで囲むとクエリは読みやすくなりますが、コストが見えにくくなることがあります。中間結果が非常に大きい場合、同等のJOINよりもプランナーが悪い実行計画を選ぶ可能性があります。

まとめ

CTEは中間クエリに名前を付けます。

  • 可読性が向上します
  • 1つのクエリ内で再利用できます
  • 再帰に必要です
  • 現代のPGではデフォルトでインライン化されます

理解度チェック

共通テーブル式を開始するキーワードは何ですか。

よくある質問

「共通テーブル式(WITH)」レッスンは無料ですか?

はい。「共通テーブル式(WITH)」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「共通テーブル式(WITH)」で何を学びますか?

ネストしたクエリを読みやすいWITH句に整理し、CTEを連結し、PostgreSQL 12以降のマテリアライズ規則を学びます。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「共通テーブル式(WITH)」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. スカラー、行、テーブルのサブクエリ
  2. 相関サブクエリと非相関サブクエリ
  3. 共通テーブル式(WITH)
  4. 階層構造向け再帰CTE
← SQL Academyに戻る