EXPLODE
UDTF будет генерировать строки структуры (один столбец типа struct), и для получения имени человека вам необходимо использовать person.name
:
WITH sample AS (
SELECT 1 AS id,
array(NAMED_STRUCT('name', 'frank',
'age', 40,
'state', 'Texas'
),
NAMED_STRUCT('name', 'maria',
'age', 51,
'state', 'Georgia'
)
)
AS array_of_structs
)
SELECT id,
person.name,
person.age
FROM sample
LATERAL VIEW explode(array_of_structs) exploded_people as person
Результат:
id,name,age
1,frank,40
1,maria,51
И INLINE
UDTF сгенерирует набор строк с N столбцами (N = количество элементов верхнего уровня в структуре), поэтому вам не нужно использовать точечную нотацию person.name
, потому что name
и другие элементы структуры уже извлечены INLINE
:
WITH sample AS (
SELECT 1 AS id,
array(NAMED_STRUCT('name', 'frank',
'age', 40,
'state', 'Texas'
),
NAMED_STRUCT('name', 'maria',
'age', 51,
'state', 'Georgia'
)
)
AS array_of_structs
)
SELECT id,
name,
age
FROM sample
LATERAL VIEW inline(array_of_structs) exploded_people as name, age, state
Результат:
id,name,age
1,frank,40
1,maria,51
Оба INLINE
и EXPLODE
являются UDTF и требуют LATERAL VIEW
в Hive. В Spark прекрасно работает без бокового обзора. Единственное отличие состоит в том, что EXPLODE
возвращает набор данных элементов массива (struct в вашем случае), а INLINE
используется для получения уже извлеченных структурных элементов. Вам нужно определить все элементы структуры в случае INLINE следующим образом: LATERAL VIEW inline(array_of_structs) exploded_people as name, age, state
С точки зрения производительности и INLINE, и EXPLODE работают одинаково, вы можете использовать команду EXPLAIN для проверки плана. Извлечение структурных элементов в UDTF или после UDTF не влияет на производительность.
INLINE требует описания всех элементов структуры (в Hive), а EXPLODE - нет, поэтому разнесение может быть более удобным, если вам не нужно извлекать все элементы структуры, если вам вообще не нужно извлекать элементы . INLINE удобен, когда вам нужно извлечь все или большинство элементов структуры.
Ваш первый пример кода работает только в Spark. В Hive 2.1.1 выдается исключение, потому что требуется lateral view
.
В Spark это также будет работать:
inline_data AS (
SELECT id,
EXPLODE(array_of_structs) as person
FROM sample
)
И чтобы получить столбец возраста, вам нужно использовать person.age