メインコンテンツへスキップ
このセクションでは、ClickHouse の SQL 構文について見ていきます。 ClickHouse は SQL ベースの構文を採用していますが、さまざまな拡張機能や最適化も提供しています。

クエリのパース

ClickHouse には 2 種類のパーサーがあります。
  • 完全な SQL パーサー (再帰下降パーサー) 。
  • データフォーマットパーサー (高速なストリームパーサー) 。
完全な SQL パーサーは、両方のパーサーを使用する INSERT クエリを除き、すべてのケースで使われます。 以下のクエリを見てみましょう。
INSERT INTO t VALUES (1, 'Hello, world'), (2, 'abc'), (3, 'def')
すでに述べたように、INSERTクエリでは 2 種類のパーサーの両方が使われます。 INSERT INTO t VALUES の部分は完全パーサーで解析され、 データ (1, 'Hello, world'), (2, 'abc'), (3, 'def') はデータフォーマットパーサー、つまり高速ストリームパーサーで解析されます。
input_format_values_interpret_expressions 設定を使うと、 データに対して完全パーサーを有効にすることもできます。前述の設定が 1 に設定されている場合、 ClickHouse はまず高速ストリームパーサーで値を解析しようとします。 それに失敗すると、ClickHouse はデータを SQL の として扱い、完全パーサーで解析しようとします。
データには任意のフォーマットを使用できます。 クエリを受信すると、server はリクエストのうち max_query_size バイトを超えない部分だけを RAM 上で処理し (デフォルトでは 1 MB) 、残りはストリームとして解析されます。 これは、大きな INSERTクエリに関する問題を避けるためです。これは、ClickHouse にデータを挿入する推奨方法でもあります。 INSERTクエリで Values フォーマットを使用する場合、 データは SELECTクエリ内の式と同じように解析されるように見えるかもしれませんが、実際にはそうではありません。 Values フォーマットは、はるかに制限が多くなっています。 この節の残りでは、完全パーサーについて説明します。
フォーマットパーサーの詳細については、Formats セクションを参照してください。

空白

  • 構文要素の間には、任意の数の空白文字を入れられます (クエリの先頭と末尾を含む) 。
  • 空白文字には、スペース、タブ、改行、CR、およびフォームフィードが含まれます。

コメント

ClickHouse は、SQL スタイルと C スタイルの両方のコメントをサポートしています。
  • SQL スタイルのコメントは --#!、または # で始まり、行末まで続きます。--#! の後のスペースは省略できます。
  • C スタイルのコメント:
    • // (または / が 3 文字以上連続するもの) の後にテキストを記述し、行末までコメントとして扱われます。/ の後にスペースは不要です。
    • 複数行コメントとして、/* から */ まで記述することもできます。この場合もスペースは不要です。
    • C スタイルのコメントはネストできます。
たとえば:
/*
 * 2つの日付の間の日数を計算します。
 * /* どちらかの引数がNULLの場合はNULLを返します */
 */
SELECT
    dateDiff('day', toDate('2024-01-01'), toDate('2024-12-31')) AS days_in_year, -- 365
    dateDiff('day', toDate('2020-01-01'), today()) AS days_since  #! 2020年以降
    ///////////////////////////////////////////////////////////////////
    # TODO: 時間/分のバリアントを追加する

キーワード

ClickHouse のキーワードは、コンテキストに応じて 大文字と小文字を区別する 場合と 大文字と小文字を区別しない 場合があります。 キーワードが 大文字と小文字を区別しない のは、次に該当するものです。
  • SQL 標準。たとえば、SELECTselectSeLeCt はいずれも有効です。
  • 一般的な DBMS (MySQL や Postgres) の一部実装。たとえば、DateTimedatetime と同じです。
データ型名が大文字と小文字を区別するかどうかは、system.data_type_families テーブルで確認できます。
標準 SQL とは異なり、そのほかのすべてのキーワード (関数名を含む) は 大文字と小文字を区別します また、キーワードは予約語ではありません。 キーワードとして扱われるのは、対応するコンテキストにおいてのみです。 キーワードと同じ名前の 識別子 を使用する場合は、二重引用符またはバッククォートで囲んでください。 たとえば、次のクエリは、テーブル table_name"FROM" という名前のカラムがある場合に有効です。
SELECT "FROM" FROM table_name

識別子

識別子には、次のものがあります。 識別子は引用符で囲むことも囲まないこともできますが、推奨されるのは後者です。 引用符で囲まない識別子は、正規表現 ^[a-zA-Z_][0-9a-zA-Z_]*$ に一致する必要があり、キーワード と同じ名前にはできません。 有効な識別子と無効な識別子の例については、以下の表を参照してください。
有効な識別子無効な識別子
xyz, _internal, Id_with_underscores_123_1x, tom@gmail.com, äußerst_schön
キーワードと同じ名前の識別子を使いたい場合や、識別子に他の記号を使いたい場合は、たとえば "id"`id` のように、二重引用符またはバッククォートで囲んでください。
引用符付き識別子のエスケープに関する規則は、文字列リテラルにも同様に適用されます。詳細については String を参照してください。
カラム名でドットを使用しないでくださいドットを含むカラム名、共通のドットプレフィックスを持つカラム、または Array 型のカラムは、flatten_nested = 1 (デフォルト) の場合、それぞれフラット化された Nested 構造の一部として解釈されることがあります。これにより、INSERT 時に予期しない配列長の検証が行われたり、名前変更に制限が生じたりする可能性があります。可能であれば、カラム名にドットを使用しないでください。 意図的に Nested のセマンティクスが必要な場合を除き、カラム名のドットの代わりにアンダースコア (_) や別の区切り文字を使用してください。

リテラル

ClickHouse では、リテラルとはクエリ内に直接記述される値のことです。 つまり、クエリの実行中に変化しない固定の値です。 リテラルには次の種類があります。 以下の各セクションで、それぞれについて詳しく見ていきます。

String

文字列リテラルはシングルクォートで囲む必要があります。ダブルクォートはサポートされていません。 エスケープは、次のいずれかの方法で行います。
  • シングルクォート文字 ' の場合に限り、直前にシングルクォートを付けて '' としてエスケープする、または
  • 直前にバックスラッシュを付け、下の表に示すサポートされているエスケープシーケンスを使用する。
バックスラッシュは、以下に挙げる文字以外の前にある場合、特別な意味を失います。つまり、文字どおりに解釈されます。
サポートされるエスケープ説明
\xHH任意個の16進数桁 (H) が続く 8 ビット文字指定。
\N予約済みで、何もしません (例: SELECT 'a\Nb'ab を返します)
\aベル
\bバックスペース
\eエスケープ文字
\f改ページ
\n改行文字
\r復帰
\t水平タブ
\v垂直タブ
\0null 文字
\\バックスラッシュ
\' (or '')シングルクォート
\"ダブルクォート
`バッククォート
\/スラッシュ
\=等号
ASCII control characters (c <= 31).
文字列リテラルでは、少なくとも '\ は、エスケープコード \' (または '') および \\ を使ってエスケープする必要があります。

Numeric

数値リテラルは、次のようにパースされます。
  • リテラルの先頭にマイナス記号 - が付いている場合、そのトークンはいったん読み飛ばされ、パース後に結果が負の値にされます。
  • 数値リテラルはまず、strtoull 関数を使って 64 ビット符号なし整数としてパースされます。
    • 値の先頭に 0b または 0x/0X が付いている場合、数値はそれぞれ 2 進数または 16 進数としてパースされます。
    • 値が負で、その絶対値が 263 を超える場合は、エラーが返されます。
  • これに失敗した場合、次に strtod 関数を使って浮動小数点数としてパースされます。
  • それ以外の場合は、エラーが返されます。
リテラル値は、その値が収まる最小の型に CAST されます。 例:
  • 1UInt8 としてパースされます
  • 256UInt16 としてパースされます。
重要64 ビットを超える整数値 (UInt128Int128UInt256Int256) を正しくパースするには、より大きい型に CAST する必要があります。
-170141183460469231731687303715884105728::Int128
340282366920938463463374607431768211455::UInt128
-57896044618658097711785492504343953926634992332820282019728792003956564819968::Int256
115792089237316195423570985008687907853269984665640564039457584007913129639935::UInt256
こうすることで上記のアルゴリズムをバイパスし、任意精度をサポートするルーチンで整数がパースされます。そうしない場合、リテラルは浮動小数点数としてパースされるため、切り捨てによって精度が失われる可能性があります。
詳細は、データ型 を参照してください。 数値リテラル内のアンダースコア _ は無視され、可読性を高めるために使えます。 次の数値リテラルがサポートされています。
数値リテラル
整数1, 10_000_000, 18446744073709551615, 01
10 進数0.1
指数表記1e100, -1e-100
浮動小数点数123.456, inf, nan
16 進数0xc0fe
SQL 標準互換の 16 進文字列x'c0fe'
2 進数0b1101
SQL 標準互換の 2 進文字列b'1101'
解釈ミスを避けるため、8 進数リテラルはサポートされていません。

複合型

Array は [] で構築します: [1, 2, 3]。Tuple は () で構築します: (1, 'Hello, world!', 2)。 厳密には、これらはリテラルではなく、それぞれ Array 作成演算子および Tuple 作成演算子を使った式です。 Array は少なくとも 1 つの要素を含んでいる必要があり、Tuple は少なくとも 2 つの要素を含んでいる必要があります。
Tuple が SELECT クエリの IN 句に現れる場合は、これとは別のケースです。 クエリ結果には Tuple を含めることができますが、Tuple をデータベースに保存することはできません (Memory エンジンを使用するテーブルを除く) 。

NULL

NULL は、値が存在しないことを示すために使用されます。 テーブルのフィールドに NULL を格納するには、そのフィールドが Nullable 型である必要があります。
NULL については、次の点に注意してください。
  • データのフォーマット (入力または出力) によって、NULL の表現は異なる場合があります。詳細は、data formats を参照してください。
  • NULL の処理には注意が必要です。たとえば、比較演算の引数のうち少なくとも 1 つが NULL の場合、その演算結果も NULL になります。これは乗算、加算、その他の演算でも同様です。各演算のドキュメントを参照することをお勧めします。
  • クエリでは、IS NULL および IS NOT NULL 演算子、ならびに関連する関数 isNullisNotNull を使用して NULL を確認できます。

ヒアドキュメント

ヒアドキュメント は、元のフォーマットを保ったまま文字列 (多くの場合、複数行) を定義する方法です。 ヒアドキュメント は、2 つの $ 記号の間に置くカスタム文字列リテラルとして定義します。 例えば:
SELECT $heredoc$SHOW CREATE VIEW my_view$heredoc$;

┌─'SHOW CREATE VIEW my_view'─┐
│ SHOW CREATE VIEW my_view   │
└────────────────────────────┘
  • 2 つのヒアドキュメントの間にある値は、“そのまま”処理されます。
  • ヒアドキュメントを使うと、SQL、HTML、XML などのコードスニペットを埋め込めます。

クエリパラメータの定義と使用

クエリパラメータを使用すると、具体的な識別子の代わりに抽象的なプレースホルダーを含む汎用的なクエリを記述できます。 クエリパラメータを含むクエリを実行すると、 すべてのプレースホルダーが解決され、実際のクエリパラメータの値に置き換えられます。 クエリパラメータは、いくつかの方法で定義できます。
  • SET param_<name>=<value> — クエリ内で SET コマンドを使用する方法。
  • --param_<name>='<value>' — コマンドラインで clickhouse-client に引数として渡す方法。
  • param_<name>=<value> — HTTP インターフェイスの URL クエリ文字列パラメータとして指定する方法。
クエリパラメータは、クエリ内で {<name>: <datatype>} を使って参照できます。ここで、<name> はクエリパラメータ名、<datatype> は変換先のデータ型です。
たとえば、次の SQL では abcd という名前のパラメータを定義しており、それぞれ異なるデータ型を持ちます。
SET param_a = 13;
SET param_b = 'str';
SET param_c = '2022-08-04 18:30:53';
SET param_d = {'10': [11, 12], '13': [14, 15]};

SELECT
   {a: UInt32},
   {b: String},
   {c: DateTime},
   {d: Map(String, Array(UInt8))};

13    str    2022-08-04 18:30:53    {'10':[11,12],'13':[14,15]}
clickhouse-client を使用している場合、パラメータは --param_name=value として指定します。たとえば、次のパラメータの名前は message で、String として取得されます。
clickhouse-client --param_message='hello' --query="SELECT {message: String}"

hello
クエリパラメータが database、table、function、またはその他の識別子の名前を表す場合は、型として Identifier を使用してください。たとえば、次のクエリは uk_price_paid という名前のテーブルから行を返します。
SET param_mytablename = "uk_price_paid";
SELECT * FROM {mytablename:Identifier};
クエリパラメータは、param_ プレフィックス付きの URL クエリ文字列パラメータとして渡せます。たとえば、次のようになります。
curl -s "http://localhost:8123/?param_message=hello" --data-binary "SELECT {message: String}"

hello
組み込みの Web UI (play.html) は、クエリ内の {name:Type} 形式のパラメータプレースホルダーを自動的に検出し、各パラメータに対応するラベル付きの入力フィールドを表示します。パラメータ値は HTTP リクエストに含まれ、さらにブックマークや共有のためにページ URL にも保持されます。
クエリパラメータは、任意の SQL クエリの任意の場所で使える汎用的なテキスト置換ではありません。 主に、識別子またはリテラルの代わりとして SELECT ステートメント内で使用することを想定して設計されています。

関数

関数呼び出しは、識別子に () で囲んだ引数のリスト (空の場合もあります) を続ける形で記述します。 標準SQLとは異なり、引数のリストが空であっても括弧は必須です。 例:
now()
以下もあります: 一部の集約関数では、括弧内に 2 つの引数リストを指定できます。例:
quantile (0.9)(x) 
これらの集約関数は「パラメトリック」関数と呼ばれ、 最初のリストにある引数は「パラメーター」と呼ばれます。
パラメーターのない集約関数の構文は、通常の関数と同じです。

演算子

演算子は、クエリのパース時に、優先順位と結合規則を考慮して対応する関数に変換されます。 たとえば、次の式では
1 + 2 * 3 + 4
に変換されます
plus(plus(1, multiply(2, 3)), 4)`

データ型とデータベースのテーブルエンジン

CREATEクエリ内のデータ型とテーブルエンジンは、識別子や関数と同じように記述します。 つまり、括弧付きの引数リストを含むことも、含まないこともあります。 詳細については、以下のセクションを参照してください。

式には、次のいずれかを指定できます。
  • 関数
  • 識別子
  • リテラル
  • 演算子の適用
  • 括弧で囲まれた式
  • サブクエリ
  • アスタリスク
また、別名を含めることもできます。 式のリストとは、1 つ以上の式をカンマで区切ったものです。 関数や演算子は、その引数として式を取ることもできます。 定数式とは、クエリ解析中、つまり実行前に結果が判明している式です。 たとえば、リテラルに対する式は定数式です。

式の別名

別名とは、クエリ内のに付けるユーザー定義の名前です。
expr AS alias
上記の構文の各部分について、以下で説明します。
構文の要素説明Example注記
AS別名を定義するためのキーワードです。AS キーワードを使わなくても、SELECT 句でテーブル名またはカラム名に別名を付けることができます。SELECT table_name_alias.column_name FROM table_name table_name_alias.CAST 関数では、AS キーワードは別の意味で使われます。関数の説明を参照してください。
exprClickHouse でサポートされる任意の式です。SELECT column_name * 2 AS double FROM some_table
aliasexpr に付ける名前です。別名は identifiers の構文に従う必要があります。SELECT "table t".column_name FROM table_name AS "table t".

使用上の注意

  • 別名はクエリまたはサブクエリ全体で有効で、任意の式に対する別名をクエリ内のどの部分でも定義できます。たとえば、次のようになります。
SELECT (1 AS n) + 2, n`.
  • 別名はサブクエリ内やサブクエリ同士の間では参照できません。たとえば、次のクエリを実行すると、ClickHouse は例外 Unknown identifier: num を返します。
`SELECT (SELECT sum(b.a) + num FROM b) - a.a AS num FROM a`
  • サブクエリのSELECT句で結果のカラムに別名が定義されている場合、これらのカラムは外側のクエリから参照できます。たとえば:
SELECT n + m FROM (SELECT 1 AS n, 2 AS m)`.
  • カラム名やテーブル名と同じ別名を付ける場合は注意してください。次の例を見てみましょう。
CREATE TABLE t
(
    a Int,
    b Int
)
ENGINE = TinyLog();

SELECT
    argMax(a, b),
    sum(b) AS b
FROM t;

Received exception from server (version 18.14.17):
Code: 184. DB::Exception: Received from localhost:9000, 127.0.0.1. DB::Exception: Aggregate function sum(b) is found inside another aggregate function in query.
前の例では、カラム b を持つテーブル t を宣言しました。 次に、データを選択する際に、sum(b) AS b という別名を定義しました。 別名はグローバルであるため、 ClickHouse は式 argMax(a, b) 内の b を式 sum(b) に置き換えました。 この置換によって例外が発生しました。
この既定の動作は、prefer_column_name_to_alias1 に設定することで変更できます。

アスタリスク

SELECTクエリでは、アスタリスクを式の代わりに使用できます。 詳しくは、SELECTのセクションを参照してください。
最終更新日 2026年6月10日