Linguagem de expressões
A linguagem formal das expressões usadas na configuração de widgets: colunas e séries calculadas, a métrica do Resumo e o agrupamento calculado da tabela. Para o passo a passo de montar uma métrica, veja o guia de colunas calculadas.
Operandos (refs)
Um operando é uma referência a uma coluna de um relatório: o nome do campo, opcionalmente precedido de um qualificador de relatório, seguido de uma chave JSON e de um sufixo de variante. Na leitura do nome-base, o qualificador é tudo que vem antes do último ponto e o campo é o último segmento.
| Forma | Sintaxe | Exemplo |
|---|---|---|
| Curta | campo | clicks |
| Qualificada | fonte.relatório.campo | googleads.campaign_performance.cost |
| Chave JSON | campo[chave] | actions[omni_purchase] |
| Variante | campo@variante | clicks@retro (uso interno) |
Identificador. Começa com letra ou _ e segue com letras, dígitos ou _. O hífen não faz parte de um identificador: nomes de relatório em kebab (campaign-performance) viram snake (campaign_performance) na forma qualificada, e digitar o hífen faz o - ser lido como subtração.
Palavras-chave reservadas. case, when, then, else, end, and, or, not, in, is, null, contains, sem diferenciar maiúsculas. Um nome nu igual a uma delas é lido como palavra-chave, não como operando. A forma qualificada escapa: um nome com ponto, colchete ou @ nunca é tratado como palavra-chave, então googleads.campaign_performance.end continua sendo operando.
Chave JSON. Uma medida em formato de mapa guarda vários valores por chave; a chave endereçada vai entre colchetes, como em actions[omni_purchase]. Tudo entre [ e o primeiro ] é a chave, inclusive pontos (é o caso dos action_types da Meta). [ sem fechar e chave vazia são erros de parse. A chave é aceita em todas as superfícies de autoria.
Sufixo @variante. Um operando pode terminar em @<variante>, sendo a variante o eixo de tempo do motor (default ou retro). É gramática válida, mas de uso interno: as fórmulas da página só enxergam a variante default, então @retro digitado por você não resolve. A variante retro é usada internamente pela comparação de período do Resumo.
Literais
| Literal | Regra | Exemplo |
|---|---|---|
| Inteiro | dígitos | 123 |
| Decimal | exige dígito depois do ponto | 1.5 |
| Separador | _ entre dígitos | 1_000 vale 1000 |
| Notação científica | e ou E, com sinal opcional | 1e3, 2.5E-2 |
| Texto | entre aspas simples; uma aspa dentro do texto se escreve dobrada (''); aspas sem fechar são erro de parse | 'facebook' |
null | o valor vazio | null |
Operadores e precedência
A gramática segue o formato do SQL. Quanto maior a precedência, mais forte o operador liga.
| Operador | Precedência | Associatividade |
|---|---|---|
or | 1 | à esquerda |
and | 2 | à esquerda |
not (prefixo) | 3 | não se aplica |
= != <> < <= > >= | 4 | à esquerda |
is null, is not null (pós-fixo) | 4 | não se aplica |
in (...), not in (...) (pós-fixo) | 4 | não se aplica |
contains '...', not contains '...' (pós-fixo) | 4 | não se aplica |
+ - (binários) | 5 | à esquerda |
* / | 6 | à esquerda |
- (unário) | liga no primário: -a * b é (-a) * b | não se aplica |
Parênteses agrupam. Palavras-chave não diferenciam maiúsculas.
| Construção | Comportamento |
|---|---|
in (a, b, ...) | testa se o valor está na lista entre parênteses, separada por vírgula; not in nega |
contains 'texto' | verdadeiro se o valor contém o texto, sem diferenciar maiúsculas; % e _ dentro do texto são literais, não curingas; not contains nega |
case when <condição> then <valor> [when ... then ...] [else <valor>] end | devolve o valor do primeiro ramo cuja condição vale; sem else e sem ramo verdadeiro, o resultado é vazio; pelo menos um when é obrigatório |
case <valor> when <v1> then ... end | forma curta: cada ramo equivale a <valor> = <v1> |
Não há funções (nem de agregação escrita à mão, nem de texto) e não há concatenação de texto.
Resolução de refs
Um nome resolve por cascata de papéis: primeiro como métrica (coluna agregada) em algum relatório disponível; se nenhum o oferece como métrica, como atributo (o rótulo da linha); senão, como dimensão (o conceito de agrupamento). Por isso uma fórmula pode comparar uma dimensão ou um atributo (campaign_name contains 'black') e ainda somar métricas.
| Situação no papel | Resultado |
|---|---|
| Exatamente um relatório atende | liga nesse relatório |
| Mais de um relatório atende | <papel> '<m>' (variant 'any') is ambiguous across [a, b], com <papel> igual a metric, attribute ou dimension |
| Nenhum papel encontra a coluna | No relation supplies operand '<m>' (variant 'any') |
Para coluna[chave], os erros equivalentes são No relation supplies JSON column '<c>' (variant 'any') e JSON column '<c>' (variant 'any') is ambiguous across [a, b].
Qualifique a ref para desambiguar. Na forma qualificada, o nome do relatório é canonizado: o prefixo dash. é removido e kebab vira snake.
O escopo de resolução é a página, não o widget. Um único conjunto reúne os relatórios declarados de cada fonte de dados registrada na página e os relatórios referenciados pelas expressões de cada widget. Todos os widgets consultam esse mesmo conjunto.
Uma expressão pode cruzar relatórios e fontes diferentes. O motor agrega cada campo dentro do seu próprio relatório e depois combina os resultados pelo agrupamento (breakdown) compartilhado; sem agrupamento, cruza os totais. Os requisitos para cruzar fontes e a restrição de autoria em gráfico e tabela estão em Limites e arestas.
Agregação
O cálculo é pós-agregação: cada métrica é agregada no grão do grupo e a fórmula roda sobre os agregados. receita / custo calcula soma(receita) / soma(custo), com proteção de denominador zero, e nunca soma(receita / custo).
As agregações possíveis de uma métrica são soma, mínimo, máximo e contagem distinta. Não há média: médias e taxas como o ROAS se expressam como razão de somas.
Uma métrica de contagem distinta é uma lista de ids (por exemplo tgsr.distinct_users.users, o KPI "Usuários" do template do TagServer). Em cada grão ela é recontada como o número de ids distintos da união das linhas, e nunca é somada entre linhas.
A linha de totais é computada no grão sem breakdown, então o total de uma razão é a razão dos totais, não a média das razões de cada linha. Pelo mesmo motivo, numa métrica de contagem distinta o total reconta os ids sobre o conjunto inteiro e pode ser menor que a soma das linhas, porque o mesmo usuário aparece em mais de uma linha.
Métricas derivadas declaradas pelo próprio relatório (por exemplo cpc = cost / clicks) são expandidas recursivamente quando referenciadas e devem usar operandos curtos; um ciclo entre elas é rejeitado.
Divisão por zero e valores ausentes
A divisão é protegida: denominador zero produz um resultado vazio, não um erro nem 0.
Um valor ausente entra como 0, seja uma medida que não aparece no período ou uma chave JSON inexistente naquela linha. Numerador ausente resulta em 0; denominador ausente resulta em vazio.
O resultado vazio aparece de forma diferente em cada superfície:
| Superfície | Resultado vazio |
|---|---|
| Preview do Resumo e play por coluna da tabela | "Sem dados" |
| Cartão do Resumo renderizado | 0 |
| Total da tabela | em branco |
| Total do gráfico | descartado |
Formato e casas decimais
| Formato | Comportamento |
|---|---|
| Número | não multiplica o valor |
| Moeda | BRL, padrão pt-BR, sem seletor de moeda |
| Percentual | multiplica o valor por 100: 0,6347 vira 63,47% |
Como o formato Percentual já multiplica por 100, a fórmula de uma taxa não deve conter * 100.
As casas decimais vão de 0 a 6. Em "Auto" (sem casas definidas), no formato Número um valor inteiro sai sem casas (1.332) e um valor com fração sai com 2 (7,39); Moeda e Percentual ficam em 2.
"Abreviar grandezas" é um toggle por métrica no gráfico e na tabela que mostra o valor abreviado (R$ 744,5 mil, 1,2 mi). Vem desligado (o valor cheio), não está disponível no formato Percentual e não existe no Resumo. Sem casas definidas, o valor abreviado usa até 1 casa; com casas definidas, respeita-as.
No gráfico e na tabela, formato, casas e abreviação de cada métrica ficam no drawer "Estilo" (o título do drawer traz "Estilo" seguido de "Tabela" ou "Gráfico"), com amostra por métrica. No Resumo, formato e casas ficam inline, junto da métrica.
Onde as expressões aparecem
| Superfície | Onde a fórmula fica | Reabrir e editar | Preview |
|---|---|---|---|
| Resumo | campo "Métrica": picker com placeholder "Escolher métrica" e o colapsável "Métrica calculada"; o valor é salvo em config.metric | o colapsável já abre expandido quando a métrica salva é uma fórmula | botão de ícone (play) com a dica "Rodar a pergunta e ver o resultado", ao lado do picker com o colapsável fechado e sobre o editor com ele aberto; mostra o valor com "resultado no período ativo", ou "Sem dados", ou o erro completo em um aviso |
| Gráfico | colapsável "Coluna calculada", botão "Adicionar coluna calculada" | não há editor no lugar | não tem preview |
| Tabela | colapsável "Coluna calculada", botão "Adicionar coluna calculada" | a coluna calculada é reconhecida ao reabrir o widget; o botão "Ver e editar a fórmula" / "Ocultar a fórmula" na linha da coluna abre o editor com a fórmula salva | play por coluna com a dica "Ver o valor desta coluna no período ativo": roda o total daquela coluna no período ativo e mostra o valor, "Sem dados" ou só a palavra "Erro" |
| Tabela, "Juntar linhas em grupos" | a expressão é o agrupamento, não a métrica; você nunca vê a expressão | não se aplica | não se aplica |
Em gráfico e tabela, a coluna calculada é a única forma de autorar uma métrica derivada: a fórmula vira a própria ref da métrica. O nome de saída é o último segmento quando a expressão é uma ref simples e expr_<id> caso contrário.
Em "Juntar linhas em grupos", você monta grupos (nome, coluna, "contém" / "não contém" / "é exatamente" / "não é" e os termos; botão "Novo grupo") e o produto os traduz num case when ... then ... else ... end desta linguagem, com contains, not contains, in e not in. Cada grupo vira uma linha. Os grupos são testados na ordem e o primeiro que casa leva a linha; o que sobra vai para uma linha de nome fixo (padrão "Outros"). Em "contém" basta um termo casar; em "não contém", nenhum pode casar.
Em todas as superfícies a expressão é parseada pelo mesmo motor, então o cálculo é idêntico; muda só onde a fórmula é guardada e como ela é rotulada. Para o formulário de cada widget, veja Configurar widgets.
Nota
A interface de "Métricas Calculadas" (o modal e o gerenciador) foi aposentada. As métricas define de widgets antigos continuam renderizando e sobrevivem intactas a um novo salvamento, mas ficam só leitura: não são criáveis nem editáveis. Para mudar a fórmula de uma delas, adicione uma coluna calculada nova e remova a antiga.
Autocomplete
| Aspecto | Comportamento |
|---|---|
| Estágios | primeiro as plataformas, depois os relatórios da plataforma escolhida, depois as métricas daquele relatório; escolher uma plataforma ou um relatório insere o segmento com o ponto e reabre o próximo estágio; só a linha de métrica completa a ref qualificada |
| Rótulos | nome amigável em pt-BR; a descrição servida da coluna é o fallback |
| Busca | ignora acentos, casa com sinônimos pt-BR/EN (digitar "custo por lead" acha cost_per_lead), pode começar de qualquer estágio e ignora palavras-chave à esquerda (completa uma ref logo após when ou then); a lista de busca livre é cortada em 40 métricas |
| Teclas | abre ao digitar ou com Ctrl+Space; Tab aceita a sugestão; Esc fecha só a lista, não o drawer |
| Escopo | os relatórios servidos (ou os conectados ao widget, quando houver), com refs qualificadas de várias fontes, não só do relatório travado |
| Colunas sugeridas | tabela: todas as colunas do relatório (métricas, dimensões e atributos); Resumo e gráfico: só métricas |
| Não entram | as colunas calculadas já adicionadas ao widget, as métricas define legadas e as chaves de uma coluna JSON (a chave [...] é digitada à mão) |
Quais campos existem em cada relatório está em Relatórios e métricas.
Erros
As mensagens de parse e de resolução aparecem em inglês, literalmente como estão abaixo. As mensagens de parse vêm seguidas de : <a expressão digitada>.
| Mensagem | Quando aparece |
|---|---|
Informe uma métrica | campo "Métrica" do Resumo vazio; é a única validação de campo que existe em qualquer superfície |
Unclosed '[' in metric expression | parse: [ sem o ] correspondente |
Empty JSON key in metric expression | parse: colchetes sem chave dentro |
Unexpected character '<c>' in metric expression | parse: caractere fora da gramática; um ! solto, sem =, cai aqui como '!' |
Unterminated string literal in metric expression | parse: texto com aspas sem fechar |
Unexpected end of metric expression | parse: a expressão termina antes de completar |
Unexpected token in metric expression | parse: elemento fora de lugar |
Expected ')' in metric expression | parse: parêntese aberto e não fechado |
Expected WHEN in metric expression | parse: case sem when |
Expected THEN in metric expression | parse: when sem then |
Expected END in metric expression | parse: case sem end |
Expected NULL in metric expression | parse: is ou is not sem null depois |
Expected '(' after IN in metric expression | parse: in sem a lista entre parênteses |
Unexpected trailing input in metric expression | parse: sobra texto depois da expressão |
No relation supplies operand '<m>' (variant 'any') | resolução: a coluna não existe em nenhum relatório disponível, em nenhum papel |
<papel> '<m>' (variant 'any') is ambiguous across [a, b] | resolução: mais de um relatório oferece a coluna no papel (metric, attribute ou dimension) |
No relation supplies JSON column '<c>' (variant 'any') | resolução: nenhum relatório disponível oferece a coluna JSON |
JSON column '<c>' (variant 'any') is ambiguous across [a, b] | resolução: mais de um relatório oferece a coluna JSON |
'<m>' is a JSON[T] column and must be accessed with <m>[<key>] | resolução: coluna em formato de mapa referenciada sem chave |
Falha ao rodar a pergunta | preview do Resumo: fallback quando o erro não traz mensagem própria |
No Resumo, o play mostra a mensagem completa. No play por coluna da tabela aparece só "Erro". O gráfico não tem preview. Não há validação no momento de adicionar a coluna: sem rodar o preview, esses erros só aparecem como o estado de erro do widget na consulta.
Limites e arestas
- Nenhuma superfície de autoria filtra caracteres. Qualquer texto é aceito no campo e o erro só surge no parse ou na resolução, via preview ou como estado de erro do widget. A única validação de campo é "Informe uma métrica", no Resumo.
@retrodigitado numa fórmula não resolve: as fórmulas da página só enxergam a variantedefault.- O hífen quebra o operando:
campaign-performance.costé lido como uma subtração. Use a forma snake. - Uma coluna com nome de palavra-chave (por exemplo
end,in,is) só é alcançável na forma qualificada. - Em gráfico e tabela não há seletor de relatório. O relatório é inferido e travado pela primeira coluna ou série escolhida (o aviso é "Mostrando colunas de um relatório. Remova as colunas para trocar de relatório."; na série do gráfico, "Remova as séries para trocar de relatório."), e o picker de colunas fica restrito a ele. Só o editor de expressão oferece refs de todos os relatórios, então uma métrica que cruza relatórios só é autorável pela coluna calculada.
- Cruzar fontes exige que os dois relatórios estejam disponíveis na página, por contas vinculadas que os forneçam, e um agrupamento compartilhado. Sem isso, o resultado é
No relation supplies operand .... - Como o escopo é a página inteira, um nome curto que resolvia pode passar a dar
is ambiguous across [...]quando outro widget da página traz um segundo relatório com a mesma coluna. - Referenciar uma coluna em formato de mapa sem chave é erro. Colunas de dimensão e atributo resolvem pela cascata de papéis;
No relation supplies operand ...só aparece quando a coluna não existe em nenhum relatório disponível. - Uma métrica
definelegada não tem editor (veja a nota em Onde as expressões aparecem). As colunas calculadas da tabela se editam no lugar.
Veja também
- Guia de colunas calculadas: o passo a passo para montar e salvar uma métrica.
- Relatórios e métricas: os campos que cada relatório oferece.
- Configurar widgets: onde a expressão entra no formulário de cada widget.