Pular para o conteúdo
Fynx
Power BI12 min de leitura

FILTER em DAX: o que faz e quando usar (com exemplos)

Guia prático de FILTER DAX: o que a função faz, sintaxe, exemplos conceituais, armadilhas de performance e boas práticas para medidas confiáveis no Power BI.

F
Fynx

FILTER resolve o que os argumentos simples do CALCULATE não conseguem

Toda vez que alguém trava numa medida que precisa de uma condição um pouco mais elaborada, a resposta quase sempre passa por FILTER DAX. É a função que você usa quando o filtro que precisa aplicar não cabe numa expressão booleana simples dentro do CALCULATE, seja porque depende de uma medida, seja porque compara colunas entre si, seja porque envolve uma lógica que o motor não aceita de forma direta. FILTER é poderoso e é justamente por isso que é o ponto onde mais gente escreve DAX que funciona no exemplo pequeno e derrete quando a tabela cresce.

Neste artigo vou direto ao ponto: o que FILTER faz de verdade, quando ele é necessário e quando é desperdício, a sintaxe com exemplos, as armadilhas de contexto e de performance que vemos toda semana em projeto de cliente, e as boas práticas que separam uma medida rápida de uma que trava o relatório. Se você ainda está construindo a base do modelo, vale ler antes nosso guia de modelagem e boas práticas de DAX, porque metade dos problemas com FILTER começa num modelo mal estruturado.

FILTER é um iterador que devolve uma tabela, não um número

A primeira coisa a entender é conceitual e muda tudo: FILTER não retorna um valor, retorna uma tabela. Ele recebe uma tabela de entrada, percorre linha por linha aplicando uma condição e devolve apenas as linhas que passaram no teste. Por isso ele é classificado como um iterador, na mesma família de SUMX e AVERAGEX.

A sintaxe é enxuta:

FILTER(<tabela>, <condição>)

O primeiro argumento é a tabela que será percorrida. Pode ser uma tabela física do modelo, como Vendas, ou uma tabela virtual gerada por outra função, como VALUES(Produtos[Categoria]) ou ALL(Clientes). O segundo argumento é a expressão booleana avaliada em cada linha, no contexto de linha que o FILTER cria.

Como FILTER devolve uma tabela, ele raramente aparece sozinho. Quase sempre está dentro de outra função que consome essa tabela: dentro de um CALCULATE como filtro, dentro de um COUNTROWS para contar as linhas que sobraram, ou dentro de um SUMX para iterar sobre o resultado. O padrão mais comum, de longe, é FILTER dentro de CALCULATE, e é sobre ele que a maioria das dúvidas gira.

Use FILTER quando a condição não cabe num argumento simples do CALCULATE

O CALCULATE aceita filtros escritos direto como argumento, no formato Tabela[Coluna] = valor. Isso é açúcar sintático: por baixo, o CALCULATE transforma essa expressão em algo próximo de um FILTER sobre os valores daquela coluna. Enquanto sua condição for uma comparação simples de uma coluna com um valor fixo ou uma lista, você não precisa escrever FILTER.

Você precisa de FILTER explícito quando cai em um destes casos:

  • A condição envolve uma medida ou uma agregação, e não apenas uma coluna. Exemplo conceitual: clientes cujo total de vendas ultrapassa um limite.
  • A condição compara duas colunas entre si na mesma linha. Exemplo: linhas onde o valor faturado é diferente do valor pedido.
  • A condição usa lógica composta que mistura colunas e expressões que o filtro simples do CALCULATE não aceita.
  • Você quer filtrar sobre uma tabela inteira com uma regra que depende do contexto de linha.

A tabela abaixo resume a decisão de forma prática.

SituaçãoEscreva assimPrecisa de FILTER?
Vendas de uma categoria específicaCALCULATE([Total], Produtos[Categoria] = "Eletrônicos")Não
Vendas de várias categoriasCALCULATE([Total], Produtos[Categoria] IN {"A","B"})Não
Clientes com total acima de um limiteCALCULATE([Total], FILTER(VALUES(Clientes[ID]), [Total] > 10000))Sim
Linhas onde faturado difere do pedidoCALCULATE([Total], FILTER(Vendas, Vendas[Fat] <> Vendas[Ped]))Sim
Produtos acima do preço médioCALCULATE([Total], FILTER(Produtos, Produtos[Preço] > [Preço Médio]))Sim

A regra mental é simples: se dá para escrever o filtro como uma comparação direta de coluna com valor, não use FILTER. Toda vez que você envolve uma coluna num FILTER sem necessidade, está pagando um custo de iteração que o motor evitaria sozinho.

O contexto de linha do FILTER é onde a maioria dos erros nasce

Quando FILTER percorre a tabela, ele cria um contexto de linha. Dentro da condição, uma referência a Vendas[Valor] aponta para o valor daquela linha específica. Até aqui tudo bem. O problema começa quando você coloca uma medida dentro da condição.

Uma medida sempre faz uma transição de contexto: ela pega o contexto de linha atual e o transforma em contexto de filtro antes de calcular. Ou seja, quando você escreve FILTER(VALUES(Clientes[ID]), [Total Vendas] > 10000), para cada cliente o motor recalcula [Total Vendas] considerando aquele cliente como filtro. Isso é exatamente o que você quer, mas é caro, porque é uma avaliação de medida por linha da tabela iterada.

Entender a diferença entre contexto de linha e contexto de filtro não é opcional para quem escreve FILTER. É o conceito que destrava tudo, e vale a pena investir tempo nele. Se ainda soa nebuloso, recomendo firmar essa base com apoio de quem já passou por isso, e nosso time trata disso o tempo todo em projetos de Power BI.

Um erro clássico é achar que FILTER(Vendas, [Total Vendas] > 100) filtra linha a linha pelo valor da linha. Não filtra. A medida [Total Vendas] dentro do FILTER, por causa da transição de contexto, é avaliada no contexto de cada linha de Vendas, o que quase nunca é o que a pessoa imaginava. Se a intenção era comparar o valor da própria linha, o correto é referenciar a coluna, Vendas[Valor] > 100, sem medida nenhuma.

FILTER sobre a tabela errada é o principal problema de performance

Aqui está o ponto que mais impacta o dia a dia. FILTER percorre a tabela que você passa no primeiro argumento. Se você passa uma tabela fato com dezenas de milhões de linhas quando bastava iterar sobre os valores distintos de uma dimensão, você acabou de multiplicar o custo por um fator absurdo.

Compare os dois padrões abaixo, que produzem o mesmo resultado lógico em muitos casos:

  • Ruim: CALCULATE([Total], FILTER(Vendas, Vendas[Categoria] = "A")) percorre a tabela fato inteira.
  • Bom: CALCULATE([Total], Vendas[Categoria] = "A") deixa o motor aplicar o filtro na coluna, sem iterar linha a linha.

Quando o FILTER é realmente necessário, ainda dá para escolher a menor tabela possível. Se a condição depende só de valores de uma coluna, itere sobre VALUES(Tabela[Coluna]) em vez da tabela inteira. O motor trabalha sobre os valores distintos, que costumam ser ordens de magnitude menos numerosos que as linhas do fato.

A tabela a seguir mostra as trocas mais comuns.

Padrão custosoAlternativa recomendadaPor quê
FILTER(Vendas, Vendas[Cat] = "A")Vendas[Cat] = "A" direto no CALCULATEEvita iterar a tabela fato
FILTER(Vendas, [Medida] > X)FILTER(VALUES(Dim[Chave]), [Medida] > X)Itera valores distintos, não linhas
Vários FILTER aninhadosUm FILTER com condição composta via &&Menos passagens sobre a tabela
FILTER dentro de coluna calculada pesadaReavaliar se cabe uma medidaColuna calculada ocupa memória no modelo

Vale reforçar: quando o filtro simples resolve, ele quase sempre é mais rápido, porque o motor consegue aplicá-lo como filtro de coluna comprimida em vez de rodar um iterador. Use FILTER porque você precisa, não por hábito.

KEEPFILTERS e o comportamento de substituição de filtro

Um detalhe que pega gente experiente: quando você usa FILTER dentro de CALCULATE sobre uma coluna que já está no contexto, o comportamento padrão do CALCULATE é substituir o filtro existente daquela coluna, não intersectar. Em muitos casos isso é o que você quer. Em outros, você quer manter o filtro que já veio do contexto visual e apenas restringir mais.

Quando a intenção é preservar o filtro externo e aplicar o seu por cima, KEEPFILTERS entra em cena, envolvendo o FILTER para que o resultado seja a interseção dos dois conjuntos de filtros, e não a substituição. Não vou aprofundar aqui porque merece um espaço próprio, mas guarde o nome: se um número parece ignorar a segmentação que o usuário selecionou, o comportamento de substituição do FILTER costuma ser o culpado.

Erros comuns que vemos em projeto de cliente

Ao revisar modelos de clientes, alguns padrões com FILTER se repetem tanto que já viraram checklist. Vale conhecer cada um antes que ele chegue no seu relatório.

  • FILTER na tabela fato quando o filtro simples resolvia. É o campeão de lentidão. Sempre pergunte se a condição não cabe direto no CALCULATE.
  • Medida dentro de FILTER sobre a tabela fato. Junta o custo da iteração da fato com o custo da transição de contexto por linha. Prefira iterar sobre a dimensão.
  • Comparar coluna com coluna esperando comportamento de agregação. Dentro do FILTER a comparação é linha a linha. Se você queria comparar totais, o desenho está errado.
  • FILTER aninhado dentro de FILTER sem necessidade. Cada nível é uma passagem a mais. Condições compostas com && e || num único FILTER costumam resolver.
  • Esquecer que FILTER substitui o filtro existente. Resultados que ignoram slicers quase sempre são isso.
  • Usar FILTER onde bastava CALCULATE com IN. Para listas de valores, IN é mais limpo e mais rápido.

Boa parte desses problemas só aparece quando o volume cresce. Um modelo que voa com dez mil linhas pode ficar inviável com dez milhões, e é aí que a conta chega. Se o seu ambiente já está nesse ponto, um trabalho de analytics avançado sobre o modelo costuma pagar o próprio custo em performance recuperada.

Boas práticas para escrever FILTER que aguenta escala

Alguns hábitos evitam a maioria das dores:

  • Comece pelo filtro simples. Só troque para FILTER quando a condição realmente exigir. Essa única disciplina resolve boa parte dos problemas de performance.
  • Escolha a menor tabela possível no primeiro argumento. VALUES de uma dimensão quase sempre vence a tabela fato.
  • Use variáveis com VAR para calcular limites e valores de referência uma vez só, fora do FILTER, em vez de recalcular a cada linha.
  • Isole a lógica em medidas nomeadas. Uma medida [Total Vendas] bem feita, reaproveitada dentro do FILTER, deixa o código legível e concentra a manutenção num lugar só.
  • Teste com volume real. Valide a medida sobre o dataset de produção, não sobre uma amostra pequena, antes de publicar.
  • Documente a intenção. FILTER com lógica composta fica ilegível rápido. Um comentário curto explicando o porquê poupa horas de quem vier depois.

Essas práticas sustentam modelos que continuam rápidos depois de anos de crescimento de dados. Para manter esse padrão em produção ao longo do tempo, vale conhecer como estruturamos a sustentação de BI para os nossos clientes.

Perguntas frequentes

Qual a diferença entre usar FILTER e passar a condição direto no CALCULATE?

O filtro direto, como Produtos[Categoria] = "A", é aplicado pelo motor como um filtro sobre os valores da coluna, sem iterar linha a linha, e por isso é mais rápido. O FILTER percorre a tabela que você indica avaliando a condição em cada linha. Use o filtro direto sempre que a condição for uma comparação simples de coluna com valor. Reserve o FILTER para quando a condição envolve medidas, comparação entre colunas ou lógica que o filtro simples não aceita.

FILTER é lento por natureza?

Não. FILTER é lento quando é aplicado sobre a tabela errada ou quando é usado onde um filtro simples resolveria. Aplicado sobre uma dimensão pequena, com a condição certa, ele é perfeitamente rápido. O problema quase nunca é a função em si, e sim o tamanho da tabela iterada e a presença de medidas na condição.

Posso usar uma medida dentro do FILTER?

Pode, e às vezes é exatamente o que você precisa, por exemplo para filtrar clientes cujo total ultrapassa um limite. Só tenha consciência de que a medida provoca transição de contexto e é reavaliada a cada linha da tabela iterada. Por isso, itere sobre os valores distintos de uma dimensão, e não sobre a tabela fato, para manter o custo sob controle.

Por que minha medida com FILTER ignora o slicer da página?

Porque, por padrão, o FILTER dentro do CALCULATE substitui o filtro existente daquela coluna em vez de intersectar com ele. Para preservar a seleção do usuário e apenas restringir mais, envolva o FILTER com KEEPFILTERS. Esse é um dos motivos mais comuns de números que parecem não respeitar as segmentações.

FILTER funciona igual em coluna calculada e em medida?

O comportamento da função é o mesmo, mas o contexto é diferente. Em coluna calculada, já existe um contexto de linha, e o resultado é materializado e ocupa memória no modelo. Em medida, o FILTER é avaliado sob demanda no contexto do visual. Na maioria dos casos de análise, a medida é a escolha certa; a coluna calculada só se justifica quando o valor precisa existir fisicamente para ser usado em relacionamentos ou segmentações.

Quando devo trocar vários FILTER aninhados por outra coisa?

Quando a lógica pode ser expressa como uma condição composta com && e || num único FILTER, quase sempre vale unificar, porque cada FILTER aninhado é uma passagem adicional sobre os dados. Se a lógica está complexa demais para caber com clareza, é sinal de que o desenho do modelo ou da medida precisa ser repensado antes de continuar empilhando funções.

Fechamento

FILTER é a função que separa quem escreve DAX que funciona de quem escreve DAX que escala. Ele resolve exatamente o que os argumentos simples do CALCULATE não alcançam, mas cobra caro quando é usado por hábito, sobre a tabela errada ou sem entender a transição de contexto. Domine três coisas e você acerta na quase totalidade dos casos: use filtro simples quando der, itere a menor tabela possível e saiba o que a medida faz dentro da condição.

Se o seu modelo já está pesado, com medidas que travam o relatório e ninguém tem certeza de onde está o gargalo, esse é o tipo de problema que resolvemos com frequência. Fale com a gente e a gente ajuda a deixar o seu Power BI rápido de novo.

Quer aplicar isso na sua empresa?

A Fynx implementa BI, Power BI e Power Platform de ponta a ponta. Conte seu cenário e devolvemos um diagnóstico direto ao ponto.

Falar com um especialista

Vamos transformar seus dados em decisão?

Conte seu cenário. Devolvemos um diagnóstico e uma proposta com faixa de investimento em poucos dias úteis, sem folheto, direto ao ponto.