Referência · DAX (Power BI)

DAX: CALCULATE, FILTER, ALL e ALLEXCEPT

CALCULATE é a função mais importante do DAX: ela recalcula uma expressão depois de mudar o contexto de filtro. FILTER escolhe linhas de uma tabela, ALL remove filtros e ALLEXCEPT remove todos, menos os que você indicar. Os exemplos abaixo usam uma tabela de vendas com cinco linhas, fácil de conferir de cabeça, e cada resultado foi obtido executando a consulta no Power BI Desktop.

Cada resultado desta página foi obtido executando a expressão no motor do Power BI Desktop (Analysis Services 17.0.57.16), em um Windows em português do Brasil. Um teste automático do Me Ajuda Flow confere que o texto da página é idêntico ao valor registrado. As expressões usam a sintaxe padrão do DAX (vírgula entre argumentos e ponto decimal); o editor do Power BI Desktop pode mostrar os separadores da configuração regional do Windows.

A tabela usada nos exemplos

Os exemplos usam esta tabela de vendas, com cinco linhas fáceis de somar de cabeça. Você pode criá-la no Power BI Desktop em Modelagem, Nova tabela:

Vendas = DATATABLE("Cliente", STRING, "Regiao", STRING, "Valor", INTEGER, "Mes", INTEGER, {{"Ana","Sul",100,1},{"Beto","Sul",200,1},{"Ana","Norte",50,2},{"Caio","Norte",300,2},{"Beto","Sul",150,3}})
ClienteRegiaoValorMes
AnaSul1001
BetoSul2001
AnaNorte502
CaioNorte3002
BetoSul1503

Exemplos executados

ExpressãoResultadoObservação
SUM(Vendas[Valor])800Soma de todas as linhas: 100 + 200 + 50 + 300 + 150.
CALCULATE(SUM(Vendas[Valor]), Vendas[Regiao] = "Sul")450O filtro Regiao = "Sul" entra no contexto: 100 + 200 + 150.
CALCULATE(SUM(Vendas[Valor]), FILTER(Vendas, Vendas[Valor] > 100))650FILTER devolve só as linhas com Valor maior que 100 (200, 300 e 150).
SUMX(Vendas, Vendas[Valor] * 2)1600SUMX percorre a tabela linha a linha e soma uma expressão: cada Valor vezes 2.
COUNTROWS(Vendas)5
DISTINCTCOUNT(Vendas[Cliente])3
AVERAGE(Vendas[Valor])160

Consulta com resultado em tabela

EVALUATE SUMMARIZECOLUMNS(Vendas[Regiao], "total", SUM(Vendas[Valor]), "geral", CALCULATE(SUM(Vendas[Valor]), ALL(Vendas[Regiao])), "pct", DIVIDE(SUM(Vendas[Valor]), CALCULATE(SUM(Vendas[Valor]), ALL(Vendas[Regiao])))) ORDER BY Vendas[Regiao]
Regiaototalgeralpct
Norte3508000.4375
Sul4508000.5625

Com ALL na coluna Regiao, o total geral (800) aparece em todas as linhas, e a divisão dá a participação de cada região.

Consulta com resultado em tabela

EVALUATE SUMMARIZECOLUMNS(Vendas[Regiao], Vendas[Mes], "mes_regiao", SUM(Vendas[Valor]), "total_regiao", CALCULATE(SUM(Vendas[Valor]), ALLEXCEPT(Vendas, Vendas[Regiao]))) ORDER BY Vendas[Regiao], Vendas[Mes]
RegiaoMesmes_regiaototal_regiao
Norte2350350
Sul1300450
Sul3150450

ALLEXCEPT mantém o filtro de Regiao e remove o de Mes: a segunda coluna mostra o total da região inteira.

Consulta com resultado em tabela

EVALUATE ADDCOLUMNS(SUMMARIZE(Vendas, Vendas[Regiao]), "sem_calc", SUM(Vendas[Valor]), "com_calc", CALCULATE(SUM(Vendas[Valor]))) ORDER BY Vendas[Regiao]
Regiaosem_calccom_calc
Norte800350
Sul800450

Sem CALCULATE, a soma dentro de ADDCOLUMNS ignora a linha atual (800 nas duas). Com CALCULATE, ela respeita a região (350 e 450).

Pegadinhas

Quando usar

Perguntas frequentes

Qual a diferença entre contexto de linha e de filtro?

O contexto de linha é a linha atual de uma iteração (como em SUMX ou em uma coluna calculada). O contexto de filtro é o conjunto de filtros que limita as linhas lidas por uma medida. O CALCULATE converte o primeiro em filtro e altera o segundo.

ALL e ALLEXCEPT são a mesma coisa?

Não. ALL remove os filtros indicados (ou todos). ALLEXCEPT remove todos os filtros da tabela, menos os das colunas que você listar.

Preciso do FILTER dentro do CALCULATE?

Só para condições que não cabem em um filtro simples de coluna, como comparar duas colunas. Para Regiao = "Sul", o filtro direto basta.

Mais páginas de DAX

Fontes oficiais