Перейти к основному содержимому
Перейти к основному содержимому

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), вы можете прочитать подколонку типа T2, используя синтаксис variant.T2, эта подколонка будет иметь тип Nullable(T2), если T2 может быть внутри Nullable, и T2 в противном случае. Эта подколонка будет такого же размера, как оригинальный столбец Variant, и будет содержать NULL значения (или пустые значения, если T2 не может быть внутри Nullable) во всех строках, в которых оригинальный столбец Variant не имеет типа T2.

Подколонки Variant также могут быть прочитаны с помощью функции variantElement(variant_column, type_name).

Примеры:

Чтобы узнать, какой вариант хранится в каждой строке, можно использовать функцию variantType(variant_column). Она возвращает Enum с именем типа варианта для каждой строки (или 'None', если строка равна NULL).

Пример:

Преобразование между столбцом Variant и другими столбцами

Существует 4 возможных преобразования, которые можно выполнить со столбцом типа Variant.

Преобразование столбца String в столбец Variant

Преобразование из String в Variant выполняется путем разбора значения типа Variant из строкового значения:

Преобразование обычного столбца в столбец Variant

Возможность преобразования обычного столбца с типом T в столбец Variant, содержащий этот тип:

Примечание: преобразование из типа String всегда выполняется через разбор, если вам нужно преобразовать столбец String в вариант String без разбора, вы можете сделать следующее:

Преобразование столбца Variant в обычный столбец

Возможно преобразовать столбец Variant в обычный столбец. В этом случае все вложенные варианты будут преобразованы в целевой тип:

Преобразование Variant в другой Variant

Можно преобразовать столбец Variant в другой столбец Variant, но только если целевой столбец Variant содержит все вложенные типы из оригинального Variant:

Чтение типа Variant из данных

Все текстовые форматы (TSV, CSV, CustomSeparated, Values, JSONEachRow и т.д.) поддерживают чтение типа Variant. При анализе данных ClickHouse пытается вставить значение в самый подходящий тип варианта.

Пример:

Сравнение значений типа Variant

Значения типа Variant могут быть сравнены только со значениями того же типа Variant.

Результат оператора < для значений v1 с базовым типом T1 и v2 с базовым типом T2 типа Variant(..., T1, ... T2, ...) определяется следующим образом:

  • Если 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.

Функции JSONExtract с Variant

Все функции JSONExtract* поддерживают тип Variant: