FLATTEN
FLATTEN BY
Преобразует строки исходной таблицы с помощью вертикального разворачивания контейнеров переменной длины (списков или словарей).
Например:
-
Исходная таблица:
[a, b, c] 1 [d] 2 [] 3 -
Таблица после вызова
FLATTEN BYк левому столбцу:a 1 b 1 c 1 d 2
В таблицах YDB не поддерживаются контейнерные типы, поэтому функция FLATTEN BY может применяться только над переменными табличных типов, создаваемых в рамках YQL запроса.
Пример
$sample = AsList(
AsStruct(AsList('a','b','c') AS value, CAST(1 AS Uint32) AS id),
AsStruct(AsList('d') AS value, CAST(2 AS Uint32) AS id),
AsStruct(AsList() AS value, CAST(3 AS Uint32) AS id)
);
SELECT value, id FROM as_table($sample) FLATTEN BY (value);
Такое преобразование может быть удобным в следующих случаях:
- Когда по ячейкам из столбца-контейнера необходимо вывести статистику (например, через
GROUP BY). - Когда в ячейках столбца-контейнера хранятся идентификаторы из другой таблицы, которую нужно присоединить с помощью
JOIN.
Синтаксис
FLATTEN BYуказывается послеFROM, но передGROUP BY, еслиGROUP BYприсутствует в запросе.- Тип столбца-результата зависит от типа исходного столбца:
| Тип контейнера | Тип результата | Комментарий |
|---|---|---|
List<X> |
X |
Тип ячейки списка |
Dict<X,Y> |
Tuple<X,Y> |
Кортеж из двух элементов с парами «ключ—значение» |
Optional<X> |
X |
Результат практически эквивалентен конструкции WHERE foo IS NOT NULL, но тип колонки foo будет изменен на X |
- По умолчанию столбец с результатом заменяет исходный. Используйте
FLATTEN BY foo AS barдля сохранения исходного контейнера. В результате исходный контейнер останется доступным вfoo, а построенный — вbar. - Чтобы построить декартово произведение нескольких столбцов-контейнеров, используйте конструкцию
FLATTEN BY (a, b, c). Скобки обязательны, чтобы избежать конфликтов в грамматике. - В
FLATTEN BYможно использовать только имена столбцов из входной таблицы. Чтобы применитьFLATTEN BYк результату вычисления, используйте подзапрос. - В
FLATTEN BYможно использовать не только столбцы, но и произвольные именованные выражения (в отличие от столбцовASобязательно). Из-за грамматических неоднозначностей выражения послеFLATTEN BYдолжны быть заключены в скобки:... FLATTEN BY (ListSkip(col, 1) AS col) ... - Если в исходном столбце были вложенные контейнеры, например
List<Dict<X,Y>>,FLATTEN BYразвернет только внешний уровень. Чтобы полностью развернуть вложенные контейнеры, используйте подзапрос.
Примечание
FLATTEN BY интерпретирует опциональные типы данных как списки длины 0 или 1. Строки таблицы с NULL пропускаются, и тип столбца меняется на аналогичный неопциональный.
FLATTEN BY делает только одно преобразование за раз, поэтому на опциональных контейнерах, например, Optional<List<String>> следует использовать FLATTEN LIST BY или FLATTEN OPTIONAL BY.
Уточнение типа контейнера
Чтобы уточнить тип контейнера, по которому необходимо произвести преобразование, можно использовать:
-
FLATTEN LIST BYДля
Optional<List<T>>операцияFLATTEN LIST BYбудет разворачивать список, интерпретируяNULL-значение как пустой список. -
FLATTEN DICT BYДля
Optional<Dict<T>>операцияFLATTEN DICT BYбудет разворачивать словарь, интерпретируяNULL-значение как пустой словарь. -
FLATTEN OPTIONAL BYЧтобы фильтровать
NULL-значения без размножения, необходимо уточнить операцию доFLATTEN OPTIONAL BY.
Примеры
SELECT
t.item.0 AS key,
t.item.1 AS value,
t.dict_column AS original_dict,
t.other_column AS other
FROM my_table AS t
FLATTEN DICT BY dict_column AS item;
SELECT * FROM (
SELECT
AsList(1, 2, 3) AS a,
AsList("x", "y", "z") AS b
) FLATTEN LIST BY (a, b);
SELECT * FROM (
SELECT
"1;2;3" AS a,
AsList("x", "y", "z") AS b
) FLATTEN LIST BY (String::SplitToList(a, ";") as a, b);
Аналоги FLATTEN BY для других СУБД
- PostgreSQL:
unnest; - Hive:
LATERAL VIEW; - MongoDB:
unwind; - Google BigQuery:
FLATTEN; - ClickHouse:
ARRAY JOIN / arrayJoin;
FLATTEN COLUMNS
Преобразует таблицу, в которой все столбцы должны являться структурами, в таблицу со столбцами, соответствующими каждому элементу каждой структуры из исходных столбцов.
Имена исходных столбцов-структур не используются и не возвращаются в результате. Имена элементов структур не должны повторяться в исходных столбцах.
Пример
SELECT x, y, z
FROM (
SELECT
AsStruct(
1 AS x,
"foo" AS y),
AsStruct(
false AS z)
) FLATTEN COLUMNS;