Análise de dados

Função QUERY do Google Sheets: guia completo de suporte

Marc Sean18 de abril de 20269 min de leitura

A função QUERY do Google Sheets suporta oito tipos de cláusulas da linguagem GQL (Google Visualization API Query Language): SELECT, WHERE, GROUP BY, PIVOT, ORDER BY, LIMIT, OFFSET e LABEL. O que ela não suporta - e é aqui que a maioria dos analistas se perde - são subconsultas, funções de janela, JOINs entre intervalos distintos e propagação confiável de valores nulos. Essas quatro limitações são onde a função quebra em modelos financeiros reais, e vale entendê-las antes de construir algo que dependa delas.

O que a função QUERY do Google Sheets suporta

O conjunto de cláusulas está documentado na referência da Google Visualization API Query Language. Em abril de 2026, ele cobre:

CláusulaO que fazFunciona entre abas?
SELECTEscolhe e reordena colunasSim
WHEREFiltra linhas por condiçãoSim
GROUP BYAgrega com SUM, AVG, COUNT, MAX, MINSim
PIVOTCria tabelas de contingênciaSim, com ressalvas
ORDER BYOrdena de forma crescente ou decrescenteSim
LIMITLimita a quantidade de linhasSim
OFFSETPula linhasSim
LABELRenomeia colunas no resultadoSim

Um exemplo prático de FP&A: extrair todas as transações acima de R$ 250 mil de um razão geral com mais de 20.000 linhas e agrupar por centro de custo - sem colunas auxiliares, sem intervalos intermediários.

=QUERY('Razão Geral'!A:F,
  "SELECT B, SUM(F)
   WHERE F > 250000
   GROUP BY B
   ORDER BY SUM(F) DESC
   LABEL SUM(F) 'Total de Despesas'",
  1)

Referências entre abas funcionam normalmente - 'Razão Geral'!A:F é sintaxe padrão. O modo como a função interpreta colunas internamente (Col1, Col2 etc. ou letras de coluna, dependendo de como a fórmula é construída) está detalhado em um post separado sobre sintaxe QUERY Col1 Col2.

A cláusula PIVOT merece atenção especial. Ela é genuinamente útil para transformar uma tabela plana de transações em uma matriz no estilo DRE sem precisar de uma tabela dinâmica. O problema: os valores das colunas de pivot precisam ser conhecidos no momento em que a fórmula é escrita, e as colunas de saída aparecem dinamicamente - o que significa que fórmulas subsequentes que referenciam colunas por posição quebram quando os dados mudam. Para relatórios de board, isso é um risco real.

O que a função QUERY do Google Sheets não suporta

Esta é a seção mais importante para quem constrói modelos com múltiplas abas. A especificação GQL deixa claro o que está fora do escopo:

Subconsultas. Não é possível aninhar um QUERY dentro de outro. Se você precisa filtrar com base em um resultado agregado - por exemplo, apenas centros de custo onde o total de despesas supera R$ 5 milhões - é preciso uma abordagem em duas etapas: primeiro um QUERY para um intervalo auxiliar e depois um QUERY nesse intervalo. É trabalhoso, mas funciona.

Funções de janela. Sem ROW_NUMBER(), sem RANK(), sem totais acumulados via OVER PARTITION BY. Para uma análise de margem de contribuição rankiada por SKU, ou você puxa os dados para uma coluna auxiliar ou aceita que o QUERY simplesmente não resolve de forma nativa.

JOINs entre intervalos distintos. O QUERY opera sobre um único intervalo contíguo. Não é possível cruzar 'DRE'!A:D com 'Headcount'!A:C dentro de uma única chamada QUERY. O contorno mais comum é a concatenação de arrays com {intervalo1, intervalo2} para unir dois intervalos antes de consultá-los - o que exige que as contagens de linhas coincidam e gera referências de coluna frágeis.

Tratamento de valores nulos. O GQL trata células em branco como nulo, mas não os propaga de forma consistente em todas as agregações. SUM ignora nulos corretamente; AVG também. Mas a sintaxe WHERE Col3 is null funciona de forma inconsistente dependendo de a célula estar genuinamente vazia ou conter uma string de comprimento zero. Na prática, adicione wrappers IFERROR e teste em uma amostra antes de usar filtros de nulo em produção.

Para ter uma referência de escala: um QUERY que condensa 50.000 linhas de transações em um resumo limpo de 30 linhas por centro de custo roda em menos de 2 segundos em uma instância moderna do Sheets. Performance não é o gargalo - são essas limitações estruturais.

Como escrever fórmulas QUERY que não quebram

O modo de falha mais comum em modelos com 8 abas interligadas são fórmulas QUERY que referenciam posições (Col1, Col2) em vez de letras de coluna. Quando alguém insere uma coluna upstream, todo QUERY baseado em posição sofre um deslocamento silencioso.

Prefira letras de coluna quando consultar um intervalo nomeado ou uma referência de aba com schema estável:

=QUERY(INDIRECT("'DRE'!A:H"),
  "SELECT A, C, D
   WHERE C >= " & Premissas!$B$3 & "
   AND D <> ''
   ORDER BY A",
  1)

Filtros de data dinâmicos - como extrair realizados até a data de fechamento do pacote para o board - funcionam concatenando o valor da célula de referência diretamente na string de consulta. O padrão Premissas!$B$3 acima é a forma correta de fazer isso. Não hardcode datas diretamente na string de consulta.

A cláusula LABEL costuma ser ignorada. Ela renomeia colunas no resultado sem tocar nos dados de origem, o que significa que os cabeçalhos da sua tabela para o board permanecem legíveis mesmo quando os nomes de coluna na fonte são abreviações técnicas. Use:

=QUERY('Receita'!A:E,
  "SELECT B, SUM(E)
   WHERE A = 'Q1'
   GROUP BY B
   LABEL B 'Unidade de Negócio', SUM(E) 'Receita Q1 (R$)'",
  1)

Para modelos com múltiplas abas: se você consulta dados em várias abas com frequência, consolide a fonte em uma única aba de staging primeiro. Um QUERY sobre um intervalo de 20.000 linhas em staging tem desempenho superior a seis QUERYs em seis abas separadas - tanto em velocidade quanto em capacidade de depuração.

Quando o QUERY deixa de ser a ferramenta certa

A limitação de JOIN é a resposta honesta para "quando devo parar de usar QUERY". Se sua análise precisa reconciliar dois conjuntos de dados - por exemplo, cruzar 3.400 notas fiscais da aba 'Contas a Pagar' com registros de pagamento na aba 'Tesouraria' pelo número da NF - o QUERY não resolve. INDEX/MATCH trata lookups um a um; SUMIFS trata lookups agregados; mas joins relacionais exigem ou uma coluna auxiliar ou algo além da sintaxe nativa do QUERY.

O outro limite que aparece na prática: agregar dados entre abas com schemas diferentes. O QUERY não consegue fazer uma union dinâmica de intervalos como 'Jan'!A:F, 'Fev'!A:F, 'Mar'!A:F a menos que você os concatene explicitamente com {'Jan'!A:F; 'Fev'!A:F; 'Mar'!A:F} - e isso se torna inviável de manter a partir de alguns meses.

A integração do ModelMonkey com DuckDB resolve esses casos permitindo que você execute SQL real sobre intervalos de planilha, incluindo joins entre abas. Na prática, a sintaxe fica assim:

SELECT ap.numero_nf, ap.valor, t.data_pagamento
FROM sheet_range('Contas a Pagar!A:D') ap
JOIN sheet_range('Tesouraria!A:C') t ON ap.numero_nf = t.numero_nf
WHERE ap.valor > 10000

Esse é o caminho de saída quando as limitações do QUERY começam a custar tempo. O artigo sobre integração do Google Sheets com DuckDB detalha a configuração.

Perguntas frequentes sobre a função QUERY do Google Sheets

A função QUERY do Google Sheets suporta JOINs entre abas diferentes?

Não. A função QUERY opera sobre um único intervalo contíguo - não é possível cruzar dois intervalos de abas distintas dentro de uma única chamada. O contorno mais comum é concatenar os dois intervalos em um array antes da consulta: {='Aba1'!A:D; 'Aba2'!A:D}. Isso exige que as colunas tenham os mesmos tipos de dado e que as contagens de linha sejam compatíveis. Para joins relacionais reais - como cruzar notas fiscais com registros de pagamento pelo número da NF - a função QUERY não é a ferramenta adequada; considere INDEX/MATCH, SUMIFS ou uma solução com SQL nativo sobre o Sheets.

Quais cláusulas a função QUERY do Google Sheets suporta?

A função suporta oito cláusulas da linguagem GQL: SELECT (seleciona e reordena colunas), WHERE (filtra linhas), GROUP BY (agrega com SUM, AVG, COUNT, MAX, MIN), PIVOT (cria tabelas de contingência), ORDER BY (ordena crescente ou decrescente), LIMIT (restringe a quantidade de linhas retornadas), OFFSET (pula um número de linhas) e LABEL (renomeia colunas no resultado). O que está fora do escopo: subconsultas aninhadas, funções de janela como RANK() e ROW_NUMBER(), JOINs entre intervalos distintos e tratamento consistente de valores nulos em todas as agregações.

Como tratar valores nulos na função QUERY do Google Sheets?

Com cautela. O GQL interpreta células em branco como nulo, mas o comportamento não é uniforme. SUM e AVG ignoram nulos corretamente. Já a sintaxe WHERE Col3 is null pode produzir resultados inconsistentes dependendo de a célula estar genuinamente vazia ou conter uma string de comprimento zero - o que acontece com frequência quando dados chegam de exportações de ERP ou importações via Apps Script. A prática recomendada é envolver a fórmula em IFERROR, usar WHERE Col3 = '' para capturar strings vazias em paralelo a is null, e validar o comportamento em uma amostra representativa dos seus dados antes de colocar o filtro em produção.

É possível usar QUERY com filtros de data dinâmicos no Google Sheets?

Sim, mas a data precisa ser concatenada diretamente na string de consulta - não referenciada como intervalo. O padrão correto é usar uma célula de referência (por exemplo, Premissas!$B$3) e construir a string assim: "WHERE A >= date '" & TEXT(Premissas!$B$3,"yyyy-mm-dd") & "'". Nunca hardcode a data diretamente na fórmula; quando o período de fechamento mudar, qualquer valor fixo vai exigir edição manual em cada fórmula que o referencia.