メインコンテンツまでスキップ
メインコンテンツまでスキップ

Variant(T1, T2, ...)

このタイプは他のデータタイプのユニオンを表します。タイプ 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) がある場合、構文 variant.T2 を使用してタイプ T2 のサブカラムを読み取ることができます。このサブカラムは、Nullable の中に T2 が含まれる場合は Nullable(T2) のタイプを持ち、それ以外の場合は T2 のタイプを持ちます。このサブカラムは元の Variant カラムと同じサイズで、元の Variant カラムに T2 タイプが含まれないすべての行に NULL 値(または NullableT2 が含まれない場合は空の値)が含まれます。

Variant サブカラムは、関数 variantElement(variant_column, type_name) を使用して読み取ることもできます。

例:

どの行にどのバリアントが格納されているかを知るには、関数 variantType(variant_column) を使用できます。この関数は、各行のバリアントタイプ名を含む Enum を返します(または行が NULL の場合は 'None' を返します)。

例:

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

Variant タイプのカラムに対して実行できる変換は4つあります。

文字列カラムを Variant カラムに変換する

String から Variant への変換は、文字列値から Variant タイプの値を解析することによって行われます:

文字列から Variant への変換中に解析を無効にするには、設定 cast_string_to_dynamic_use_inference を無効にできます:

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

タイプ T の通常のカラムを、これらのタイプを含む Variant カラムに変換できます:

注意: String タイプからの変換は常に解析を通じて行われます。もし、文字列カラムを解析なしで Variant の文字列バリアントに変換する必要がある場合は、次のようにできます:

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

Variant カラムを通常のカラムに変換できます。この場合、すべてのネストされたバリアントが目的のタイプに変換されます:

Variantを別の Variant に変換する

Variant カラムを別の Variant カラムに変換できますが、目的の Variant カラムが元の Variant のすべてのネストされたタイプを含む場合のみです:

データからバリアントタイプを読み取る

すべてのテキストフォーマット(TSV、CSV、CustomSeparated、Values、JSONEachRowなど)はVariant タイプの読み取りをサポートしています。データ解析中に ClickHouse は値を最も適切なバリアントタイプに挿入しようとします。

例:

Variant タイプの値の比較

Variant タイプの値は、同じ Variant タイプの値間でのみ比較できます。

< 演算子の結果は、基になるタイプ T1 の値 v1 と基になるタイプ T2 の値 v2 に対して次のように定義されます:

  • T1 = T2 = T の場合、結果は v1.T < v2.T(基になる値が比較されます)。
  • T1 != T2 の場合、結果は T1 < T2(タイプ名が比較されます)。

例:

特定の Variant 値を持つ行を見つけるには、次のいずれかを行うことができます:

  • 値を対応する Variant タイプにキャストします:
  • 特定のタイプで Variant サブカラムを比較します:

時には、異なるタイプを持つ行に対して複雑なタイプ(例: Array/Map/Tuple)のサブカラムを使って追加のチェックを行うことが役立つことがあります。これらのタイプは Nullable の中には存在できず、異なるタイプの行には NULL の代わりにデフォルト値が使用されます:

注意: 異なる数値タイプを持つバリアントの値は互いに異なるバリアントと見なされ、相互に比較されません。これらのタイプ名が比較されます。

例:

注意: デフォルトでは、GROUP BY/ORDER BY キーに Variant タイプは許可されていません。使用する場合は、特別な比較ルールを考慮し、allow_suspicious_types_in_group_by/allow_suspicious_types_in_order_by 設定を有効にしてください。

JSONExtract 関数と Variant

すべての JSONExtract* 関数は Variant タイプをサポートしています: