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
値(または Nullable
に T2
が含まれない場合は空の値)が含まれます。
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
タイプをサポートしています: