メインコンテンツへスキップ
この型は、他のデータ型のユニオンを表します。型 Variant(T1, T2, ..., TN) は、この型の各行が T1 型、T2 型、…、TN 型のいずれか、またはいずれにも該当しない (NULL 値) 値を持つことを意味します。 ネストされた型の順序は重要ではありません: Variant(T1, T2) = Variant(T2, T1)。 ネストできる型は、Nullable(…)、LowCardinality(Nullable(…))、Variant(…) 型を除く任意の型です。
類似した型をバリアントとして使用することは推奨されません (たとえば、Variant(UInt32, Int64) のような異なる数値型や、Variant(Date, DateTime) のような異なる日付型) 。 そのような型の値を扱うと曖昧さが生じる可能性があるためです。デフォルトでは、このような Variant 型を作成すると例外が発生しますが、設定 allow_suspicious_variant_types を使用すると有効にできます。

Variant の作成

テーブルのカラム定義で Variant 型を使用するには:
通常のカラムで CAST を使用する場合:
引数に共通の型がない場合に if/multiIf 関数を使用するには (この場合、設定 use_variant_as_common_type を有効にする必要があります) :
配列要素またはマップの値に共通の型がない場合は、関数 ‘array/map’ を使用します (これを使用するには、設定 use_variant_as_common_type を有効にする必要があります) :

サブカラムとして Variant のネストされた型を読み取る

Variant 型では、型名をサブカラムとして使うことで、Variant カラムから特定のネストされた型だけを読み取れます。 たとえば、variant Variant(T1, T2, T3) というカラムがある場合、型 T2 のサブカラムは variant.T2 という構文で読み取れます。 このサブカラムの型は、T2Nullable に含められる場合は Nullable(T2)、そうでない場合は T2 になります。このサブカラムは 元の Variant カラムと同じサイズを持ち、元の Variant カラムが型 T2 ではないすべての行には NULL 値 (または T2Nullable に含められない場合は空の値) が入ります。 Variant のサブカラムは、関数 variantElement(variant_column, type_name) を使って読み取ることもできます。 例:
各行に格納されている Variant 型を確認するには、関数 variantType(variant_column) を使用できます。これは、各行の Variant 型の型名を表す Enum を返します (行が NULL の場合は 'None') 。 例:

Variant カラムと他のカラム間の変換

Variant 型のカラムに対しては、4 種類の変換を実行できます。

String カラムを Variant カラムに変換する

String から Variant への変換は、文字列値をパースして Variant 型の値に変換することで行われます。
String から Variant への変換時にパースを無効にするには、設定 cast_string_to_dynamic_use_inference をオフにします。

通常のカラムを Variant カラムに変換する

T の通常のカラムは、この型を持つ Variant カラムに変換できます。
注: String 型からの変換は常にパースを経由して行われます。パースせずに String カラムを Variant 型の String バリアントに変換する必要がある場合は、次のようにします:

Variant カラムを通常のカラムに変換する

Variant カラムは通常のカラムに変換できます。この場合、ネストされたすべての Variant の値は宛先の型に変換されます:

Variant を別の Variant に変換する

Variant カラムは別の Variant カラムに変換できますが、変換先の Variant カラムに元の Variant のすべてのネストされた型が含まれている場合に限ります。

データから Variant 型を読み取る

すべてのテキストフォーマット (TSV、CSV、CustomSeparated、Values、JSONEachRow など) は、Variant 型の読み取りをサポートしています。データのパース時に、ClickHouse は値を最も適切な Variant 型として挿入しようとします。 例:

Variant 型の値の比較

Variant 型の値は、同じ Variant 型の値とのみ比較できます。 デフォルトでは、比較演算子は Variant のデフォルト実装 を使用し、 各 Variant 型ごとに個別に比較を行います。これは、設定 use_variant_default_implementation_for_comparisons = 0 を使用して無効にし、以下で説明するネイティブな Variant 比較ルールを使用できます。: ORDER BY では常にネイティブ比較が使用されます。 ネイティブな Variant 比較ルール: Variant(..., T1, ... T2, ...) において、内部の型 T1 を持つ値 v1 と、内部の型 T2 を持つ値 v2 に対する演算子 < の結果は、次のように定義されます。
  • T1 = T2 = T の場合、結果は v1.T < v2.T です (内部値が比較されます) 。
  • T1 != T2 の場合、結果は T1 < T2 です (型名が比較されます) 。
例:
特定の Variant 値を持つ行を見つけるには、次のいずれかの方法を使用できます。
  • 値を対応する Variant 型にキャストします。
  • Variant のサブカラムを必要な型と比較します:
場合によっては、追加で Variant 型 を確認すると便利です。これは、Array/Map/Tuple のような複雑な型を持つサブカラムは Nullable に含めることができず、型が異なる行では NULL ではなくデフォルト値になるためです。
注: 数値型が異なる Variant の値は別の Variant として扱われ、値同士は相互に比較されません。代わりに、型名が比較されます。 例:
注記 デフォルトでは、Variant 型は GROUP BY/ORDER BY キーでは使用できません。使用する場合は、その特殊な比較ルールを考慮したうえで、allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by 設定を有効にしてください。

Variant を引数に取る JSONExtract 関数

すべての JSONExtract* 関数で Variant 型がサポートされています。

Variant 引数を持つ関数

ClickHouse のほとんどの関数は、Variant 用のデフォルト実装によって Variant 型の引数を自動的にサポートします。 バージョン 26.1 以降では、Variant 型を明示的に処理しない関数に Variant カラムが渡されると、ClickHouse は次のように動作します。
  1. Variant カラムから各 Variant 型を抽出する
  2. 各 Variant 型ごとに関数を個別に実行する
  3. 結果の型に応じて適切に結果をまとめる
これにより、特別な処理をしなくても、通常の関数を Variant カラムに対して使用できます。 例:
比較演算子は各 Variant 型に個別に自動適用されるため、Variant カラムに対するフィルタリングが可能です。 結果型の挙動: 結果型は、関数が各 Variant に対して返す値によって決まります。
  • 結果型が異なる場合: Variant(T1, T2, ...)
  • 型に互換性がない場合: 互換性のない Variant では NULL
エラー処理: 関数が Variant 型を処理できない場合、型関連のエラー (ILLEGAL_TYPE_OF_ARGUMENT, TYPE_MISMATCH, CANNOT_CONVERT_TYPE, NO_COMMON_TYPE) のみが捕捉され、該当する行の結果は NULL になります。ゼロ除算やメモリ不足などのその他のエラーは、 実際の問題が見えなくならないよう、通常どおり送出されます。

型不一致時の動作

設定 variant_throw_on_type_mismatch は、Variant カラムに関数を適用した際、その行に実際に格納されている型が関数と互換性がない場合の動作を制御します。
  • true (デフォルト) — 最初の非互換な行で例外 (ILLEGAL_TYPE_OF_ARGUMENT) をスローします。
  • false — 非互換な行では NULL を返し、互換性のある行については結果を返します。
例:
最終更新日 2026年7月2日