Ir para o conteúdo principal

Pivot SQL: Convertendo Linhas em Colunas

SQL Pivot: Converting Rows to Columns

Publicado: 1 de novembro de 2018

Código aberto6 min de leitura

Experimente este notebook no Databricks

Confira o ebook Por que o Data Lakehouse é o seu Próximo Data Warehouse para descobrir o funcionamento interno da Databricks Lakehouse Platform.

ATUALIZADO EM 11/10/2018

O PIVOT foi introduzido pela primeira vez no Apache Spark 1.6 como um novo recurso do DataFrame que permite aos usuários girar uma expressão do tipo tabela, transformando os valores únicos de uma coluna em colunas individuais.

A versão Apache Spark 2.4 estende essa poderosa funcionalidade de pivotação de dados para nossos usuários SQL também. Neste artigo, usando registros de temperatura em Seattle, mostraremos como podemos usar esse recurso comum de PIVOT SQL para realizar transformações complexas de dados.

Examinando as Temperaturas de Verão com PIVOT

Neste verão em Seattle, as temperaturas subiram para níveis desconfortáveis, atingindo máximas de 30-32°C por nove dias em julho.

Data Temp (°F)
07-22-2018 86
07-23-2018 90
07-24-2018 91
07-25-2018 92
07-26-2018 92
07-27-2018 88
07-28-2018 85
07-29-2018 94
07-30-2018 89

Suponha que queremos explorar ou examinar se houve uma tendência histórica no aumento dos níveis de mercúrio. Uma maneira intuitiva de examinar e apresentar esses números é ter os meses como colunas e, em seguida, as médias mensais máximas de cada ano em uma única linha. Dessa forma, será fácil comparar as temperaturas tanto horizontalmente, entre meses adjacentes, quanto verticalmente, entre anos diferentes.

Agora que temos suporte para a sintaxe PIVOT no Spark SQL, podemos conseguir isso com a seguinte consulta SQL.

A consulta acima produzirá um resultado como:

YEAR JAN FEB MAR APR MAY JUNE JULY AUG SEPT OCT NOV DEC
2018 49.7 45.8 54.0 58.6 70.8 71.9 82.8 79.1 NULL NULL NULL NULL
2017 43.7 46.6 51.6 57.3 67.0 72.1 78.3 81.5 73.8 61.1 51.3 45.6
2016 49.1 53.6 56.4 65.9 68.8 73.1 76.0 79.5 69.6 60.6 56.0 41.9
2015 50.3 54.5 57.9 59.9 68.0 78.9 82.6 79.0 68.5 63.6 49.4 47.1

Bem, parece que há anos bons e anos ruins. O ano de 2016 parece ter sido um ano relativamente econômico em termos de energia.

Pivotação em SQL

Vamos dar uma olhada mais de perto nesta consulta para entender como ela funciona. Primeiro, precisamos especificar a cláusula FROM, que é a entrada para o pivô, em outras palavras, a tabela ou subconsulta na qual o pivô será realizado. No nosso caso, estamos interessados nos anos, nos meses e nas temperaturas máximas, então esses são os campos que aparecem na subconsulta.

Segundo, vamos considerar outra parte importante da consulta, a cláusula PIVOT. O primeiro argumento da cláusula PIVOT é uma função de agregação e a coluna a ser agregada. Em seguida, especificamos a coluna de pivô na sub-cláusula FOR como o segundo argumento, seguido pelo operador IN contendo os valores da coluna de pivô como o último argumento.

A coluna de pivô é o ponto em torno do qual a tabela será girada, e os valores da coluna de pivô serão transpostos para colunas na tabela de saída. A cláusula IN também permite especificar um alias para cada valor de pivô, facilitando a geração de nomes de coluna mais significativos.

Uma ideia importante sobre o pivô é que ele realiza uma agregação agrupada com base em uma lista de colunas de group-by implícitas, juntamente com a coluna de pivô. As colunas de group-by implícitas são colunas da cláusula FROM que não aparecem em nenhuma função de agregação ou como coluna de pivô.

Na consulta acima, com a coluna de pivô sendo a coluna mês e a coluna de group-by implícita sendo a coluna ano, a expressão avg(temp) será agregada em cada par de valores distintos de (year, month), onde o mês é igual a um dos valores especificados da coluna de pivô. Como resultado, cada um desses valores agregados será mapeado para sua célula correspondente da linha year e coluna month.

Vale notar que, por causa desse group-by implícito, precisamos garantir que qualquer coluna que não desejamos que faça parte da saída do pivô seja omitida da cláusula FROM, caso contrário, a consulta produziria resultados indesejados.

e-books

Um guia prático para aplicativos no Databricks

Especificando Múltiplas Expressões de Agregação

O exemplo acima mostra apenas uma expressão de agregação sendo usada na cláusula PIVOT, enquanto, na verdade, os usuários podem especificar múltiplas expressões de agregação, se necessário. Novamente, com os dados meteorológicos acima, podemos listar as temperaturas máximas junto com as temperaturas médias entre junho e setembro.

No caso de múltiplas expressões de agregação, as colunas serão o produto cartesiano dos valores da coluna de pivô e das expressões de agregação, com os nomes como _.

year JUN_avg JUN_max JUL_avg JUL_max AUG_avg AUG_max SEP_avg SEP_max
2018 71.9 88 82.8 94 79.1 94 NULL NULL
2017 72.1 96 78.3 87 81.5 94 73.8 90
2016 73.1 93 76.0 89 79.5 95 69.6 78
2015 78.9 92 82.6 95 79.0 92 68.5 81

Colunas de Agrupamento vs. Colunas de Pivô

Agora, suponha que queremos incluir as temperaturas baixas em nossa exploração das tendências de temperatura a partir desta tabela de temperaturas baixas diárias:

Data Temp (°F)
... ...
08-01-2018 59
08-02-2018 58
08-03-2018 59
08-04-2018 58
08-05-2018 59
08-06-2018 59
... ...

Para combinar esta tabela com a tabela anterior de temperaturas máximas diárias, poderíamos juntar essas duas tabelas pela coluna “Data”. No entanto, como vamos usar o pivô, que realiza agrupamento nas datas, podemos simplesmente concatenar as duas tabelas usando UNION ALL. E você verá mais tarde, essa abordagem também nos oferece mais flexibilidade:

Agora vamos tentar nossa consulta de pivô com a nova tabela combinada:

Como resultado, obtemos a média das temperaturas altas e a média das temperaturas baixas para cada mês dos últimos 4 anos em uma única tabela. Observe que precisamos incluir a coluna flag na consulta PIVOT, caso contrário, a expressão avg(temp) seria baseada em uma mistura de temperaturas altas e baixas.

year H/L JUN JUL AUG SEP
2018 H 71.9 82.8 79.1 NULL
2018 L 53.4 58.5 58.5 NULL
2017 H 72.1 78.3 81.5 73.8
2017 L 53.7 56.3 59.0 55.6
2016 H 73.1 76.0 79.5 69.9
2016 L 53.9 57.6 59.9 52.9
2015 H 78.9 82.6 79.0 68.5
2015 L 56.4 59.9 58.5 52.5

Você pode ter notado que agora temos duas linhas para cada ano, uma para as temperaturas altas e outra para as baixas. Isso ocorre porque incluímos mais uma coluna, flag, na entrada do PIVOT, que por sua vez se torna outra coluna de agrupamento implícita, além da coluna original year.

Alternativamente, em vez de ser uma coluna de agrupamento, a flag também pode servir como uma coluna PIVOT. Assim, agora temos duas colunas PIVOT, month e flag:

Esta consulta nos apresenta um layout diferente dos mesmos dados, com uma linha para cada ano, mas duas colunas para cada mês.

year JUN_hi JUN_lo JUL_hi JUL_lo AUG_hi AUG_lo SEP_hi SEP_lo
2018 71.9 53.4 82.8 58.5 79.1 58.5 NULL NULL
2017 72.1 53.7 78.3 56.3 81.5 59.0 73.8 55.6
2016 73.1 53.9 76.0 57.6 79.5 57.9 69.6 52.9
2015 78.9 56.4 82.6 59.9 79.0 58.5 68.5 52.5

Próximos Passos

Para executar os exemplos de consulta usados neste blog, consulte os exemplos de SQL PIVOT neste notebook acompanhante.

Obrigado aos contribuidores da comunidade Apache Spark por suas contribuições!

(Esta publicação no blog foi traduzida utilizando ferramentas baseadas em inteligência artificial) Publicação original

Nunca perca uma postagem da Databricks

Inscreva-se nas categorias de seu interesse e receba as últimas postagens na sua caixa de entrada