跳到主要内容
跳到主要内容

Variant(T1, T2, ...)

Beta feature. Learn more.

此类型表示其他数据类型的联合。类型 Variant(T1, T2, ..., TN) 表示该类型的每一行具有类型 T1T2 或 ... 或 TN 的值,或者为 none(NULL 值)。

嵌套类型的顺序无关:Variant(T1, T2) = Variant(T2, T1)。 嵌套类型可以是任意类型,但不能是 Nullable(...)、LowCardinality(Nullable(...)) 和 Variant(...) 类型。

备注

不建议将相似的类型作为变体使用(例如不同的数值类型如 Variant(UInt32, Int64) 或不同的日期类型如 Variant(Date, DateTime)),因为处理这类类型的值可能会导致歧义。默认情况下,创建这样的 Variant 类型会导致异常,但可以通过设置 allow_suspicious_variant_types 来启用。

备注

Variant 数据类型是一项测试版功能。要使用它,请设置 enable_variant_type = 1

创建 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 的子列,如果 T2 可以嵌入 Nullable,则该子列将具有类型 Nullable(T2),否则将是 T2。该子列的大小与原始 Variant 列相同,在所有原始 Variant 列没有类型 T2 的行中将包含 NULL 值(或空值如果 T2 不能嵌入 Nullable)。

Variant 子列也可以使用函数 variantElement(variant_column, type_name) 读取。

示例:

要知道每行存储的变体,可以使用函数 variantType(variant_column)。它返回每行的 Enum,对应变体类型名称(如果行是 NULL,则返回 'None')。

示例:

Variant 列与其他列之间的转换

可以执行四种可能的转换,从 Variant 类型的列中生成。

将字符串列转换为变体列

StringVariant 的转换通过解析字符串值中的 Variant 类型的值进行:

将普通列转换为变体列

可以将类型为 T 的普通列转换为包含此类型的 Variant 列:

注意:从 String 类型的转换总是通过解析进行的,如果你需要将 String 列转换为不进行解析的 VariantString,可以执行以下操作:

将变体列转换为普通列

可以将 Variant 列转换为普通列。在这种情况下,所有嵌套的变体将被转换为目标类型:

将变体转换为另一个变体

可以将 Variant 列转换为另一个 Variant 列,但仅当目标 Variant 列包含所有原始 Variant 的嵌套类型时:

从数据读取 Variant 类型

所有文本格式(TSV、CSV、自定义分隔、值、JSONEachRow 等)均支持读取 Variant 类型。在数据解析过程中,ClickHouse 升尝试将值插入最合适的变体类型。

示例:

比较变体类型的值

Variant 类型的值只能与相同 Variant 类型的值进行比较。

操作符 < 对于具有底层类型 T1T2 的值 v1v2 的结果如下定义:

  • 如果 T1 = T2 = T,则结果为 v1.T < v2.T (底层值将被比较)。
  • 如果 T1 != T2,则结果为 T1 < T2 (类型名称将被比较)。

示例:

如果你需要查找特定 Variant 值的行,可以执行以下操作之一:

  • 将值转换为相应的 Variant 类型:
  • 用需要的类型比较 Variant 子列:

有时,进行额外检查可能会很有用,因为嵌套子列如 Array/Map/Tuple 这类复杂类型可能无法嵌入 Nullable,并且对于具有不同类型的行将具有默认值而不是 NULL

**注意:**具有不同数值类型的变体的值被视为不同的变体,彼此之间不进行比较,而是比较它们的类型名称。

示例:

注意 默认情况下,Variant 类型不能用于 GROUP BY / ORDER BY 键,如果你想使用它,请考虑其特殊的比较规则,并启用 allow_suspicious_types_in_group_by / allow_suspicious_types_in_order_by 设置。

使用 Variant 的 JSONExtract 函数

所有 JSONExtract* 函数支持 Variant 类型: