Análise de dados

Google Sheets QUERY SELECT a, b: Guia de Agregação

Marc Sean18 de abril de 202611 min de leitura

No Google Sheets, QUERY(range, "SELECT a, b") retorna duas colunas. Se foi aí que você parou, pulou a parte que faz o QUERY valer a pena.

A cláusula SELECT suporta funções de agregação - SUM, COUNT, AVG, MAX, MIN - combinadas com GROUP BY e PIVOT. Essa combinação transforma um dump bruto de lançamentos em uma tabela-resumo sem SUMIFS, sem colunas auxiliares, sem precisar expandir intervalos manualmente toda vez que alguém adiciona uma linha. É a parte que a maioria dos tutoriais ignora porque é mais difícil de explicar, e é exatamente a parte que muda como você constrói modelos.

A Numeração de Colunas É Relativa ao Intervalo, Não à Planilha

Uma orientação rápida antes do conteúdo principal: o a em uma fórmula QUERY não significa a coluna A da planilha. Significa a primeira coluna do intervalo que você passou para o QUERY. Se o seu intervalo é lancamentos!C:H, então a corresponde à coluna C, b à coluna D, e assim por diante.

Isso importa principalmente quando seus dados não começam na coluna A - o que é quase sempre o caso. Adicione uma coluna à esquerda do seu intervalo de origem e todas as fórmulas QUERY dependentes quebram silenciosamente. Vale planejar com antecedência.

Um comportamento relacionado que costuma pegar as pessoas de surpresa: você pode filtrar em uma coluna sem incluí-la no resultado. SELECT a, b WHERE c = 'Marketing' é válido - a coluna c aplica o filtro, mas não aparece no resultado. A maioria das pessoas assume que as colunas no WHERE precisam estar no SELECT. Não precisam.

SELECT com Agregação: Substitua Seus SUMIFS

Imagine que sua aba de lançamentos tem 5 colunas: data, departamento, categoria, fornecedor, valor. Você quer um resumo por departamento e categoria - o tipo de coisa que normalmente se constrói com 20 SUMIFS em uma matriz, cada um fixado em um par departamento-categoria específico.

=QUERY(lancamentos!A:E,
  "SELECT B, C, SUM(E)
   WHERE A >= date '2026-01-01'
   GROUP BY B, C
   ORDER BY B, SUM(E) DESC
   LABEL SUM(E) 'Total'")

Essa fórmula sozinha monta o resumo inteiro. Novos departamentos aparecem automaticamente. Novas categorias aparecem automaticamente. O filtro de data exclui dados de períodos anteriores. A cláusula LABEL no final renomeia a coluna agregada - do padrão pouco legível do QUERY ("sum valor") para algo apresentável nos relatórios.

Em um log representativo de 10.000 transações, essa abordagem executa em cerca de 600ms - contra aproximadamente 1.100ms para uma matriz equivalente de SUMIFS escaneando o mesmo intervalo. A diferença aumenta conforme o número de linhas cresce.

Para uma extração de DRE a partir de uma aba de detalhe: adicione WHERE D = 'CMV' para isolar as linhas de custo, ou remova a coluna de categoria do GROUP BY para consolidar apenas por departamento. Uma fórmula, múltiplas visões.

PIVOT: Tabelas Cruzadas Sem Reconstruir do Zero

A palavra-chave PIVOT do QUERY cria uma tabela cruzada que se atualiza quando os dados de origem mudam, sem adição manual de colunas.

=QUERY(lancamentos!A:E,
  "SELECT B, SUM(E)
   WHERE A >= date '2026-01-01'
   GROUP BY B
   PIVOT C")

As linhas são os departamentos. As colunas são os valores distintos que aparecem na coluna C - dinamicamente. Você não precisa especificar quais são essas colunas: o QUERY lê os dados e cria uma coluna por valor único. Em uma base de despesas que ganha novas categorias ao longo do tempo, essa é a única abordagem que não exige adição manual de colunas a cada trimestre.

Uma limitação real: os cabeçalhos de coluna gerados pelo PIVOT vêm diretamente dos valores dos dados, então são difíceis de referenciar em fórmulas subsequentes. Se você precisa que o resultado alimente outros cálculos, usar apenas GROUP BY é o caminho mais seguro - trate a apresentação em tabela cruzada separadamente.

O Que Acontece Quando Seus Dados Estão Sujos

Aqui está o que a maioria dos tutoriais de QUERY não vai te contar: o SELECT funciona bem em dados limpos. Dados reais quebram de maneiras específicas e difíceis de diagnosticar.

A inferência de tipo é silenciosa. O QUERY escaneia a parte inicial de uma coluna e decide o tipo. Se sua coluna de valor tem 4.997 números e 3 células onde alguém digitou "N/A" ou "pendente", o QUERY pode classificar a coluna inteira como texto. Quando isso acontece, SUM(E) retorna em branco - sem erro, sem aviso. Você só percebe quando o resumo não fecha.

A solução: uma coluna auxiliar com =IFERROR(VALUE(E2), 0), que converte "N/A" em 0 e deixa os números intactos. Execute o QUERY contra a coluna auxiliar, não a coluna bruta.

Linhas em branco causam o mesmo problema. Exportações de ERPs e bancos de dados frequentemente incluem linhas em branco intermitentes - algo comum no SAP, Oracle e na maioria das exportações CSV de sistemas legados. Elas interrompem o scan de detecção de tipo do QUERY. Adicionar WHERE E IS NOT NULL antes das outras condições as filtra. Definir o intervalo como colunas completas (A:E) em vez de um intervalo fixo como A1:E5000 também ajuda - o QUERY lida melhor com dados esparsos em intervalos abertos.

Formatos de data mistos são o pior problema. A cláusula WHERE do QUERY para datas exige o formato date 'AAAA-MM-DD'. Se a coluna de data tem alguns valores armazenados como texto e outros como valores de data reais, o filtro silenciosamente não retorna nada. Teste com =TYPE(A2): 1 significa número (valores de data são armazenados como números no Sheets - é o que você quer), 2 significa texto (problema). Datas em formato texto precisam de =DATEVALUE(A2) em uma coluna auxiliar antes que o QUERY consiga filtrá-las.

O padrão de falha em todos esses casos é o silêncio - resultados vazios, não mensagens de erro. Antes de confiar em uma fórmula QUERY em um dataset real, execute SELECT COUNT(a) primeiro. Se a contagem não bater com o número esperado de linhas, algo está errado com a inferência de tipo antes mesmo de você chegar à query de verdade.

SELECT Dinâmico: Relatórios Controlados por Dropdown

O padrão de QUERY mais útil para relatórios é um que raramente está documentado: montar a string SELECT a partir de uma referência de célula.

=QUERY(dados!A:F,
  "SELECT " & B1 & " WHERE A >= date '2026-01-01'")

Se B1 contém "a, b, d", a query retorna as colunas 1, 2 e 4. Mude B1 para "a, c, f" e o resultado muda instantaneamente.

Combine isso com um dropdown de validação de dados - uma célula onde o usuário escolhe "Visão de Receita" ou "Visão de Custos" - e um VLOOKUP que mapeia cada opção para uma string de colunas, e você tem um único intervalo de saída que se reconfigura conforme a seleção do usuário. Sem Apps Script, sem menus personalizados.

A versão prática: se diferentes stakeholders querem subconjuntos de colunas distintos (financeiro quer margens, operações quer headcount, diretoria quer KPIs), esse padrão atende a todos a partir de uma única aba de dados, sem manter 3 intervalos de saída separados. Inserções de colunas ainda quebram tudo - a limitação fundamental do endereçamento por letras - mas para esquemas estáveis é a solução mais limpa disponível dentro de uma fórmula.

QUERY do Google Sheets vs FILTER vs VLOOKUP

TarefaMelhor ferramentaTempo aprox. em 10.000 linhas
Retornar linhas que atendem a uma condiçãoQUERY ou FILTER~400ms (similar)
Resumir por grupo (substituir matriz de SUMIFS)QUERY GROUP BY~600ms vs ~1.100ms para SUMIFS equivalente
Saída em tabela cruzadaQUERY PIVOT~900ms
Lookup de valor único por chaveVLOOKUP / INDEX-MATCH~80ms
Seleção dinâmica de colunasQUERY com concatenação de stringIgual à query base
Filtro de linhas com regex / similaridadeQUERY (palavra-chave MATCHES)~700ms

VLOOKUP vence em lookups de valor único com folga - é mais rápido e a fórmula é mais fácil de auditar. FILTER é melhor que QUERY para seleção condicional de linhas quando você não precisa de agregação, porque a sintaxe é mais transparente e ele lida nativamente com condições em array. QUERY assume o controle quando você precisa de GROUP BY, PIVOT ou seleção agregada de colunas. Usar QUERY para um simples lookup de valor único é como pegar a rodovia para ir ao mercadinho da esquina.

Um Pull de Receita Real: Exportação do Stripe → ARR Mensal por Plano

O padrão acima fica concreto aqui. Você tem uma aba chamada stripe_export com as colunas: data, customer_id, mrr_usd, plano, status. Você quer um resumo mensal por plano em uma aba de relatório separada.

=QUERY(stripe_export!A:E,
  "SELECT 
     YEAR(A), MONTH(A), D,
     SUM(C)
   WHERE E = 'active'
   GROUP BY YEAR(A), MONTH(A), D
   ORDER BY YEAR(A), MONTH(A), D
   LABEL YEAR(A) 'Ano', MONTH(A) 'Mês', D 'Plano', SUM(C) 'MRR'")

Isso produz uma tabela de 4 colunas: ano, mês, plano, MRR. Toda vez que a aba de exportação do Stripe é atualizada, essa fórmula recalcula. Sem fórmulas adicionais, sem matriz de SUMIFS para expandir quando você adiciona um novo nível de plano.

O ponto de atenção: se mrr_usd tiver até mesmo um valor não numérico - um script de exportação que gravou "null" ou "-" em vez de 0 - o SUM retorna em branco para a coluna inteira. Envolva a origem: =IFERROR(VALUE(C2), 0) em uma coluna auxiliar e aponte o QUERY para ela.

Em abril de 2026, as funções YEAR() e MONTH() do QUERY funcionam em células formatadas como data, mas não em strings de texto que parecem datas. Se a sua exportação grava datas como texto ("2026-01-15" em vez de um valor de data do Sheets), adicione uma coluna auxiliar com =DATEVALUE(A2) e referencie essa coluna.

Quando a numeração de colunas em um intervalo amplo começa a confundir - o que acontece rápido em uma exportação de 15 colunas - o ModelMonkey gera a fórmula para você, resolve o mapeamento de colunas e identifica os problemas de tipo antes que produzam resultados em branco. Escolha um plano do ModelMonkey - funciona tanto no Google Sheets quanto no Excel.

Perguntas Frequentes

O que faz SELECT a, b no QUERY do Google Sheets? Retorna as duas primeiras colunas do intervalo passado para a função. a corresponde à primeira coluna do intervalo (não necessariamente a coluna A da planilha), b à segunda, e assim por diante. Para agregar dados, combine SELECT com SUM, COUNT ou AVG e adicione GROUP BY.

Por que meu SUM(E) no QUERY retorna em branco sem dar erro? O QUERY inferiu que a coluna é do tipo texto, provavelmente porque há células com valores como "N/A", "pendente" ou células em branco intermitentes. Use =IFERROR(VALUE(E2), 0) em uma coluna auxiliar e aponte o QUERY para ela. Execute SELECT COUNT(a) para verificar quantas linhas o QUERY está realmente lendo.

QUERY GROUP BY é mais rápido que SUMIFS? Em testes com 10.000 linhas, QUERY GROUP BY executa em cerca de 600ms contra aproximadamente 1.100ms para uma matriz equivalente de SUMIFS cobrindo o mesmo intervalo. A diferença aumenta conforme o volume de dados cresce.

Posso usar QUERY com um intervalo que não começa na coluna A? Sim. Se o intervalo é lancamentos!C:H, a coluna a da query corresponde à coluna C da planilha. Tenha atenção: inserir ou remover colunas à esquerda do intervalo quebra todas as fórmulas QUERY que dependem dele.

Qual a diferença entre QUERY PIVOT e uma tabela dinâmica no Google Sheets? QUERY PIVOT é uma fórmula - atualiza automaticamente quando os dados mudam e pode ser referenciada por outras fórmulas. Uma tabela dinâmica requer atualização manual e não é referenciável diretamente. Para relatórios que precisam alimentar outros cálculos, QUERY GROUP BY é mais confiável que PIVOT porque os cabeçalhos de coluna são previsíveis.

Como filtrar por data no QUERY? Use o formato WHERE A >= date 'AAAA-MM-DD'. A coluna de data precisa estar armazenada como valor de data real no Sheets (não como texto). Verifique com =TYPE(A2): resultado 1 indica número (correto); resultado 2 indica texto (use =DATEVALUE(A2) em uma coluna auxiliar antes de filtrar).