共通テーブル式(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フィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- スカラー、行、テーブルのサブクエリ
- 相関サブクエリと非相関サブクエリ
- 共通テーブル式(WITH)
- 階層構造向け再帰CTE