Nivelar matrizes aninhadas - Amazon Athena

Nivelar matrizes aninhadas

Ao trabalhar com matrizes aninhadas, você normalmente precisa expandir elementos de matriz aninhados para uma única matriz ou expandir a matriz para várias linhas.

Exemplos

Para nivelar elementos de uma matriz aninhada em uma única matriz de valores, use a função flatten. Essa consulta retorna uma linha para cada elemento na matriz.

SELECT flatten(ARRAY[ ARRAY[1,2], ARRAY[3,4] ]) AS items

Essa consulta retorna:

+-----------+ | items | +-----------+ | [1,2,3,4] | +-----------+

Para nivelar uma matriz em várias linhas, use CROSS JOIN com o operador UNNEST, como neste exemplo:

WITH dataset AS ( SELECT 'engineering' as department, ARRAY['Sharon', 'John', 'Bob', 'Sally'] as users ) SELECT department, names FROM dataset CROSS JOIN UNNEST(users) as t(names)

Essa consulta retorna:

+----------------------+ | department | names | +----------------------+ | engineering | Sharon | +----------------------| | engineering | John | +----------------------| | engineering | Bob | +----------------------| | engineering | Sally | +----------------------+

Para nivelar uma matriz de pares chave/valor, transpor chaves selecionadas para colunas, como neste exemplo:

WITH dataset AS ( SELECT 'engineering' as department, ARRAY[ MAP(ARRAY['first', 'last', 'age'],ARRAY['Bob', 'Smith', '40']), MAP(ARRAY['first', 'last', 'age'],ARRAY['Jane', 'Doe', '30']), MAP(ARRAY['first', 'last', 'age'],ARRAY['Billy', 'Smith', '8']) ] AS people ) SELECT names['first'] AS first_name, names['last'] AS last_name, department FROM dataset CROSS JOIN UNNEST(people) AS t(names)

Essa consulta retorna:

+--------------------------------------+ | first_name | last_name | department | +--------------------------------------+ | Bob | Smith | engineering | | Jane | Doe | engineering | | Billy | Smith | engineering | +--------------------------------------+

Em uma lista de funcionários, selecione o funcionário com a maior pontuação combinada. UNNEST pode ser usado na cláusula FROM sem um CROSS JOIN anterior pois ele é o operador de junção padrão e, portanto, implícito.

WITH dataset AS ( SELECT ARRAY[ CAST(ROW('Sally', 'engineering', ARRAY[1,2,3,4]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))), CAST(ROW('John', 'finance', ARRAY[7,8,9]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))), CAST(ROW('Amy', 'devops', ARRAY[12,13,14,15]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))) ] AS users ), users AS ( SELECT person, score FROM dataset, UNNEST(dataset.users) AS t(person), UNNEST(person.scores) AS t(score) ) SELECT person.name, person.department, SUM(score) AS total_score FROM users GROUP BY (person.name, person.department) ORDER BY (total_score) DESC LIMIT 1

Essa consulta retorna:

+---------------------------------+ | name | department | total_score | +---------------------------------+ | Amy | devops | 54 | +---------------------------------+

Em uma lista de funcionários, selecione o funcionário com a pontuação individual mais alta.

WITH dataset AS ( SELECT ARRAY[ CAST(ROW('Sally', 'engineering', ARRAY[1,2,3,4]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))), CAST(ROW('John', 'finance', ARRAY[7,8,9]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))), CAST(ROW('Amy', 'devops', ARRAY[12,13,14,15]) AS ROW(name VARCHAR, department VARCHAR, scores ARRAY(INTEGER))) ] AS users ), users AS ( SELECT person, score FROM dataset, UNNEST(dataset.users) AS t(person), UNNEST(person.scores) AS t(score) ) SELECT person.name, score FROM users ORDER BY (score) DESC LIMIT 1

Essa consulta retorna:

+--------------+ | name | score | +--------------+ | Amy | 15 | +--------------+

Considerações e limitações

Se a função UNNEST for usada em uma ou mais matrizes na consulta e uma das matrizes for NULL, a consulta não retornará nenhuma linha. Se a função UNNEST for usada em uma matriz que é uma string vazia, a string vazia será retornada.

Por exemplo, na consulta apresentada a seguir, como a segunda matriz é nula, a consulta não retorna nenhuma linha.

SELECT col1, col2 FROM UNNEST (ARRAY ['apples','oranges','lemons']) AS t(col1) CROSS JOIN UNNEST (ARRAY []) AS t(col2)

No próximo exemplo, a segunda matriz foi modificada para conter uma string vazia. Para cada linha, a consulta retorna o valor em col1 e uma string vazia para o valor em col2. A string vazia na segunda matriz é necessária para que os valores na primeira matriz sejam retornados.

SELECT col1, col2 FROM UNNEST (ARRAY ['apples','oranges','lemons']) AS t(col1) CROSS JOIN UNNEST (ARRAY ['']) AS t(col2)