共通テーブル式
SELECT クエリ内の任意の場所で、名前を使って参照できます。
名前付きサブクエリは、現在のクエリのスコープ内、または子サブクエリのスコープ内で、名前を使って参照できます。
SELECT クエリ内で共通テーブル式を参照すると、CTE が明示的にマテリアライズされていない限り、常にその定義元のサブクエリに置き換えられます (Materialized Common Table Expressions を参照) 。
再帰は、識別子解決の処理で現在の CTE を見えなくすることで防止されます。
CTE は、呼び出されたすべての箇所で同じ結果になることを保証しない点に注意してください。これは、使用されるたびにクエリが再実行されるためです。
構文
例
1000000 が表示されるはずです
しかし、cte_numbers を 2 回参照しているため、そのたびに乱数が生成され、結果として 280501, 392454, 261636, 196227 など、毎回異なる値が表示されます…
マテリアライズド共通テーブル式
MATERIALIZED キーワードを追加すると、ClickHouse は CTE のサブクエリを 一度だけ 実行し、その結果を一時テーブルに格納して、以降のすべての参照でそのテーブルを使用します。
これは、同じ CTE が 1 つのクエリ内で複数回参照される場合 (たとえば自己結合や複数の IN サブクエリ) に特に有用です。元の計算が一度しか行われないためです。
マテリアライズド CTE は 実験的 な機能です。
利用するには、アナライザ が必要であり、設定
enable_materialized_cte も有効になっている必要があります。構文
マテリアライズド CTEを使用する場面
- 1つのクエリ内で同じCTEが複数回参照される場合。
MATERIALIZEDを使用しないと、参照のたびにサブクエリがそれぞれ再実行されます。 - CTEに
generateRandomのような非決定論的関数が含まれている場合。 マテリアライズすることで、すべての参照で同じデータを参照できます。 - CTEに、繰り返し実行すべきでない高コストな計算 (集計、JOIN、大規模スキャン) が含まれている場合。
例
MATERIALIZED がない場合、JOIN の両側でそれぞれ独立にサブクエリが実行されます。
MATERIALIZED がある場合、テーブルは一度だけスキャンされ、JOIN の両側は同じ一時テーブルを読み取ります。
generateRandom を使うと、参照するたびに異なる結果になります。
CTE をマテリアライズすると、一貫した結果が得られます:
1000000 になります。
例 3: 実体化された CTE のチェーン
実体化された CTE は、別の実体化された CTE を参照できます。
ClickHouse は依存関係を解決し、それらを正しい順序で実体化します。
制限事項
- 実験的な設定が必要: 設定
enable_materialized_cteを有効にする必要があります。 - アナライザが必要: マテリアライズド CTE は、アナライザ が有効な場合にのみ動作します (
enable_analyzer = 1) 。 RECURSIVEでは未サポート:MATERIALIZEDキーワードとRECURSIVEキーワードを組み合わせることはできず、UNSUPPORTED_METHOD例外が発生します。- 相関 CTE は使用不可: マテリアライズド CTE では、外側のクエリスコープのカラムを参照できません。
共通スカラ式
WITH 句で任意のスカラ式に別名を定義できます。
共通スカラ式は、クエリ内のどの場所からでも参照できます。
構文
例
extension は gen_name ラムダ関数の本体内では束縛されていません。
extension は generated_names の定義および使用のスコープでは共通スカラ式として '.txt' に定義されていますが、generated_names サブクエリ内で利用可能であるため、テーブル extension_list のカラムとして解決されます。
SELECT句のカラムリストから sum(bytes) 式の結果を除外する
再帰クエリ
RECURSIVE修飾子を使うと、WITHクエリ内でそのクエリ自身の出力を参照できます。例:
例: 1 から 100 までの整数の合計
再帰 CTE は、バージョン
24.3 で導入された クエリアナライザ に依存しています。24.3+ を使用していて (UNKNOWN_TABLE) または (UNSUPPORTED_METHOD) 例外が発生する場合は、インスタンス、ロール、またはプロファイルでアナライザが無効になっている可能性があります。アナライザを有効にするには、設定 allow_experimental_analyzer を有効にするか、compatibility 設定をより新しいバージョンに更新してください。
バージョン 24.8 以降、アナライザは正式機能となり、設定 allow_experimental_analyzer は enable_analyzer に名称変更されました。WITH クエリの一般的な形式は、常に非再帰項、続いて UNION ALL、その後に再帰項が続く形です。このうち、クエリ自身の出力への参照を含められるのは再帰項だけです。再帰 CTE クエリは次のように実行されます。
- 非再帰項を評価します。非再帰項クエリの結果を一時的な作業テーブルに格納します。
- 作業テーブルが空でない限り、次の手順を繰り返します。
- 再帰項を評価し、再帰的な自己参照を作業テーブルの現在の内容に置き換えます。再帰項クエリの結果を一時的な中間テーブルに格納します。
- 作業テーブルの内容を中間テーブルの内容で置き換え、その後、中間テーブルを空にします。
検索順序
サイクル検出
Maximum recursive CTE evaluation depth エラーで失敗します。
無限クエリ
LIMIT を使用する場合は、無限再帰 CTE クエリも使用できます。
例: 無限再帰 CTE クエリ
末尾のカンマ
WITH句では、最後の要素の後にもカンマを付けられます。