A fórmula QUERY é o equivalente mais próximo de SQL que existe no Google Sheets - e para quem trabalha com FP&A, isso importa mais do que a maioria dos analistas percebe. Um único =QUERY() consegue substituir uma pilha de SOMASES aninhados, retornar uma visão filtrada do P&L em 10.000 linhas e ainda ordenar o resultado, tudo em uma única célula. A sintaxe segue o dialeto SQL da Google Visualization API, não o SQL padrão, mas depois que você entende as diferenças ela é mais rápida de escrever do que a maioria das alternativas com fórmulas.
Uma ressalva antes de começar: se os seus dados de origem vêm de exportação de ERP - SAP, TOTVS, Sankhya - espere encontrar colunas com tipos mistos. O QUERY determina o tipo de uma coluna pela maioria dos valores e silenciosamente ignora as células que não batem. Em uma análise de variação de 8.000 linhas, isso significa que 5% dos seus lançamentos podem simplesmente sumir sem nenhum erro visível. Isso não é um caso extremo: é o padrão em dados de GL exportados no Brasil. A seção de limitações detalha como contornar, mas vale entrar neste artigo já sabendo que limpeza de dados não é opcional.
Este artigo não é uma introdução à sintaxe. É sobre onde o QUERY de fato se justifica em um modelo financeiro, onde ele falha e quando vale a pena usar outra coisa.
O que o QUERY faz que o SOMASES não consegue
SOMASES agrega. QUERY retorna linhas. Essa é a diferença central, e é ela que determina qual ferramenta usar em cada situação.
Quando você está montando uma visão de margem de contribuição por linha de produto para um board pack, o SOMASES obriga a escrever uma fórmula por métrica por linha. O QUERY permite retornar o recorte inteiro de uma vez - todas as linhas onde linha_produto = "Enterprise", ordenadas por receita decrescente, com uma linha de cabeçalho no topo. O resultado se expande automaticamente, o que significa que se atualiza sempre que os dados de origem mudam.
De acordo com a Google Visualization API Query Language Reference (Google LLC, consultada em 19 de abril de 2026), a função executa "uma consulta nos dados usando a Google Visualization API Query Language." Essa linguagem suporta SELECT, WHERE, GROUP BY, ORDER BY, LIMIT e LABEL - aproximadamente 80% do que você usaria em uma consulta de relatório convencional.
Sintaxe entre abas para modelos com múltiplas planilhas
A parte que a maioria dos tutoriais ignora: referenciar outra aba. A sintaxe exige que o intervalo seja envolvido dentro da própria chamada da função:
=QUERY('DRE'!A:H, "SELECT A, B, C, SUM(F) WHERE B = 'Enterprise' GROUP BY A, B, C LABEL SUM(F) 'Receita'", 1)
O terceiro argumento (1) informa ao QUERY quantas linhas de cabeçalho a fonte possui. Esqueça esse argumento e o cabeçalho é tratado como linha de dados, o que quebra as agregações.
Em um modelo onde uma aba de Premissas alimenta tudo, um filtro de data dinâmico fica assim:
=QUERY('DRE'!A:H, "SELECT A, B, SUM(F) WHERE A >= date '"&TEXTO(Premissas!$B$3,"yyyy-mm-dd")&"' GROUP BY A, B", 1)
O formato de data importa exatamente aqui. Os literais de data do QUERY precisam seguir o padrão yyyy-mm-dd, entre aspas simples dentro da string SQL. Um formato incorreto retorna um erro de parse que parece problema nos dados - até você parar para depurar.
Cláusulas WHERE para filtragem dinâmica
A cláusula WHERE suporta AND, OR e NOT. Para uma análise de variação onde você quer realizado versus orçado no 1T2026, filtrado por um centro de custo específico:
=QUERY('Detalhes GL'!A:J, "SELECT B, D, SUM(G), SUM(H) WHERE C = 'CC-412' AND A >= date '2026-01-01' AND A <= date '2026-03-31' GROUP BY B, D ORDER BY SUM(G) DESC", 1)
Isso retorna departamento, conta, realizado e orçado para um centro de custo ao longo do primeiro trimestre - ordenado por gasto realizado, para que as maiores variações apareçam primeiro. O equivalente em SOMASES seriam 4 fórmulas por linha, replicadas manualmente para cada código de conta relevante.
Uma restrição não óbvia: o QUERY não consegue referenciar intervalos nomeados dentro da string SQL. A referência de coluna precisa ser uma letra (A, B, C) ou a notação Col1, Col2. Intervalos nomeados funcionam como argumento de fonte de dados, mas não dentro da string de consulta. Isso pega muita gente quando tentam WHERE conta = IntervaloNomeado - a fórmula falha silenciosamente e retorna tudo.
Agregações e GROUP BY
O GROUP BY do QUERY substitui tabelas dinâmicas quando o objetivo é saída programática. A regra: toda coluna no SELECT que não seja uma função de agregação precisa aparecer no GROUP BY. Violar isso gera o erro "Column X cannot both be aggregated and not aggregated".
Funções de agregação suportadas: SUM, COUNT, AVG, MAX, MIN. Sem MEDIAN, sem DESVPAD, sem funções de percentil - esse é o teto. Para qualquer coisa além dessas cinco, você precisará pós-processar a saída do QUERY com fórmulas adicionais ou usar ARRAYFORMULA com funções mais granulares.
Conforme o histórico de versões do Google Workspace (Google LLC, consultado em 19 de abril de 2026), o conjunto de funções de agregação do QUERY não recebeu expansão desde 2018. Se você precisa da mediana do EBITDA por trimestre, use o QUERY para puxar e ordenar as linhas, depois aplique MED ao intervalo resultante com uma fórmula auxiliar.
LABEL, FORMAT e controle da saída
Duas cláusulas que raramente aparecem em tutoriais mas fazem diferença em relatórios prontos para apresentação:
LABEL renomeia os cabeçalhos das colunas no resultado. Sem ela, colunas agregadas herdam nomes como SUM Receita ou avg(E) - aceitável para uso interno, constrangedor em um PDF exportado para a diretoria.
=QUERY('Receita'!A:F, "SELECT A, B, SUM(C) GROUP BY A, B LABEL A 'Período', B 'Segmento', SUM(C) 'Receita Líquida (R$ mil)'", 1)
FORMAT aplica um formato de exibição à saída, usando as mesmas strings de formato que a função TEXTO(). Para colunas de valores monetários em um board pack:
"... LABEL SUM(C) 'Receita Líquida' FORMAT SUM(C) '#.##0'"
Isso mantém o número subjacente como numérico - fórmulas em outras partes do modelo ainda conseguem referenciá-lo - enquanto a exibição fica limpa.
Exemplo completo: aba de Relatórios conectada ao GL
Este é o modelo que você pode copiar diretamente. Ele resolve ao mesmo tempo os três problemas mais comuns em produção: filtro de data amarrado a uma célula de referência central, células em branco tratadas com IS NOT NULL e cabeçalhos já prontos para board pack.
Estrutura assumida da aba Detalhes GL:
| Col | Conteúdo |
|---|---|
| A | Data do lançamento |
| B | Centro de custo |
| C | Conta contábil |
| D | Descrição da conta |
| G | Valor realizado (R$) |
| H | Valor orçado (R$) |
Célula de referência: Premissas!$B$3 contém a data de início do período (ex: 01/01/2026) e Premissas!$B$4 contém a data de fim (ex: 31/03/2026).
Fórmula na aba Relatórios:
=QUERY(
'Detalhes GL'!A:H,
"SELECT B, C, D, SUM(G), SUM(H)
WHERE A IS NOT NULL
AND A >= date '"&TEXTO(Premissas!$B$3,"yyyy-mm-dd")&"'
AND A <= date '"&TEXTO(Premissas!$B$4,"yyyy-mm-dd")&"'
GROUP BY B, C, D
ORDER BY SUM(G) DESC
LABEL B 'Centro de Custo',
C 'Conta',
D 'Descrição',
SUM(G) 'Realizado (R$)',
SUM(H) 'Orçado (R$)'",
1
)
O IS NOT NULL antes dos filtros de data é obrigatório: sem ele, qualquer célula em branco na coluna A quebra a fórmula inteira ao filtrar por intervalo. O LABEL já entrega cabeçalhos prontos - o sócio vê "Realizado (R$)" no PDF, não "SUM G". Para alterar o período de análise, basta atualizar as células de referência em Premissas; a aba de Relatórios se recalcula automaticamente.
Se você quiser restringir a um centro de custo específico, adicione um AND antes do GROUP BY:
AND B = '"&Premissas!$B$5&"'
Onde Premissas!$B$5 contém o código do centro de custo (ex: CC-412). A aba de Relatórios passa a funcionar como um painel paramétrico: muda a célula, muda a visão.
Onde a fórmula QUERY falha na prática
Três modos de falha que vale conhecer - o primeiro deles, como mencionado na abertura, é o mais perigoso em dados de GL reais:
Tipos mistos em uma coluna. O QUERY determina o tipo da coluna com base na maioria dos valores. Se a coluna B é 95% texto mas tem 5 células numéricas, o QUERY a trata como texto e silenciosamente ignora os números nas comparações do WHERE. Em exportações de ERP, isso é mais regra do que exceção: campos de conta que deveriam ser texto às vezes chegam como número dependendo do perfil de exportação. Limpe os dados de origem, adicione uma coluna auxiliar que force tipos consistentes com =TEXTO(A2,"@"), ou inclua uma linha de validação que conte o total de registros e compare com a soma que o QUERY retorna.
Células em branco em colunas de data. Uma célula em branco em uma coluna de data faz o QUERY retornar erro ao filtrar por intervalo de datas. A solução é WHERE A IS NOT NULL AND A >= date '...', como mostrado no exemplo acima. Garantir que o intervalo de origem não tenha células em branco no final do dataset também ajuda.
Referências dinâmicas de aba. Não é possível referenciar dinamicamente um nome de aba dentro do QUERY da forma que se faz com INDIRETO. =QUERY(INDIRETO("'"&A1&"'!A:H"), ...) funciona para o intervalo, mas a string de consulta ainda precisa de letras de coluna fixas. Em modelos onde a estrutura das abas muda, isso torna o QUERY frágil de formas que o SOMASES não é.
QUERY versus SOMASES: critério de decisão
Use QUERY quando você precisa de linhas de volta - listas filtradas, recortes dinâmicos de relatórios, saída ordenada. Use SOMASES quando você precisa de um único valor agregado em uma célula fixa que outras fórmulas referenciam. O erro clássico é usar SOMASES para construir o que é essencialmente uma tabela filtrada, o que exige replicar a fórmula manualmente linha a linha e coluna a coluna.
| Critério | QUERY | SOMASES |
|---|---|---|
| Retorna múltiplas linhas | ✓ | ✗ |
| Retorna valor único para outras fórmulas | ✗ | ✓ |
| Ordena o resultado automaticamente | ✓ | ✗ |
| Renomeia cabeçalhos de colunas | ✓ | ✗ |
| Referencia intervalo nomeado na lógica | ✗ | ✓ |
| Tolerante a tipos mistos na coluna | ✗ | ✓ |
| Ideal para aba de relatórios/saída | ✓ | ✗ |
| Ideal para motor de cálculo (downstream) | ✗ | ✓ |
Um modelo de três demonstrações com uma aba dedicada de Relatórios puxando dados de Detalhes GL é um caso natural para o QUERY. A aba de relatórios se mantém atualizada automaticamente, o LABEL cuida da nomenclatura das colunas e o ORDER BY faz os dados que o CFO quer ver aparecerem sem ordenação manual. As abas de cálculo - DRE projetada, fluxo de caixa, análise de sensibilidade - continuam usando SOMASES embaixo, onde valores únicos alimentam fórmulas downstream sem depender do comportamento de expansão do QUERY.
Se você já usa automação com IA no seu fluxo de trabalho no Google Sheets, o QUERY combina bem: a IA pode gerar ou modificar a string SQL enquanto mantém a estrutura das suas fórmulas intacta.
Perguntas frequentes
Como referenciar outra aba na fórmula QUERY?
Use a sintaxe 'NomeDaAba'!Intervalo como primeiro argumento da função, por exemplo 'DRE'!A:H. Inclua sempre o terceiro argumento com o número de linhas de cabeçalho (geralmente 1) para evitar que o cabeçalho seja interpretado como dado.
Por que minha fórmula QUERY retorna erro ao filtrar datas?
Os literais de data dentro da string SQL precisam seguir obrigatoriamente o formato yyyy-mm-dd entre aspas simples: date '2026-01-01'. Além disso, células em branco na coluna de data causam erro - adicione IS NOT NULL à cláusula WHERE antes dos filtros de intervalo.
O QUERY consegue usar intervalos nomeados?
Intervalos nomeados funcionam como argumento de fonte de dados (primeiro argumento), mas não dentro da string SQL. Dentro da consulta, as colunas precisam ser referenciadas por letra (A, B, C) ou pela notação Col1, Col2. Tentar WHERE conta = MeuIntervalo na string SQL falha silenciosamente.
Qual a diferença entre QUERY e FILTER no Google Sheets? FILTER retorna linhas com base em condições booleanas simples, sem suporte a agregação, ordenação ou renomeação de cabeçalhos. QUERY é mais poderoso para relatórios, mas FILTER é mais intuitivo para filtragem rápida sem precisar escrever SQL. Para modelos de FP&A com saída formatada, QUERY geralmente compensa o custo extra de sintaxe.
O QUERY suporta MEDIAN ou outras funções estatísticas? Não. As únicas agregações suportadas são SUM, COUNT, AVG, MAX e MIN. Para mediana ou desvio padrão, use o QUERY para extrair e ordenar as linhas e aplique as funções MED ou DESVPAD do Sheets ao intervalo resultante com uma fórmula auxiliar.
O QUERY funciona com dados de outras planilhas (arquivos diferentes)? Não diretamente. O primeiro argumento do QUERY precisa referenciar um intervalo no mesmo arquivo. Para puxar dados de outra planilha, use primeiro IMPORTRANGE para trazer os dados para uma aba auxiliar e aplique o QUERY sobre esse intervalo importado.
Resumo
A fórmula QUERY produz saída filtrada, ordenada e agregada por linhas em uma única expressão. Referências entre abas funcionam com a sintaxe padrão 'NomeDaAba'!Intervalo mais um argumento de cabeçalho. Filtros de data exigem formatação de string yyyy-mm-dd e IS NOT NULL para tratar células em branco. As agregações suportam cinco funções (SUM, COUNT, AVG, MAX, MIN) - nada além disso. Em modelos de FP&A, o QUERY pertence às abas de relatórios e saída; o SOMASES pertence ao motor de cálculo, onde valores únicos alimentam fórmulas downstream. E antes de colocar qualquer QUERY em produção sobre dados de ERP, valide os tipos de coluna - o comportamento silencioso com tipos mistos é o modo de falha que mais dói quando descoberto tarde.
O ModelMonkey consegue gerar e iterar fórmulas QUERY de forma conversacional - útil quando você está construindo uma nova visão de relatório e não quer depurar sintaxe de string SQL manualmente. Escolha um plano do ModelMonkey - funciona tanto no Google Sheets quanto no Excel.