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.
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}})
| Cliente | Regiao | Valor | Mes |
|---|---|---|---|
| Ana | Sul | 100 | 1 |
| Beto | Sul | 200 | 1 |
| Ana | Norte | 50 | 2 |
| Caio | Norte | 300 | 2 |
| Beto | Sul | 150 | 3 |
Exemplos executados
| Expressão | Resultado | Observação |
|---|---|---|
SUM(Vendas[Valor]) | 800 | Soma de todas as linhas: 100 + 200 + 50 + 300 + 150. |
CALCULATE(SUM(Vendas[Valor]), Vendas[Regiao] = "Sul") | 450 | O filtro Regiao = "Sul" entra no contexto: 100 + 200 + 150. |
CALCULATE(SUM(Vendas[Valor]), FILTER(Vendas, Vendas[Valor] > 100)) | 650 | FILTER devolve só as linhas com Valor maior que 100 (200, 300 e 150). |
SUMX(Vendas, Vendas[Valor] * 2) | 1600 | SUMX 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]
| Regiao | total | geral | pct |
|---|---|---|---|
Norte | 350 | 800 | 0.4375 |
Sul | 450 | 800 | 0.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]
| Regiao | Mes | mes_regiao | total_regiao |
|---|---|---|---|
Norte | 2 | 350 | 350 |
Sul | 1 | 300 | 450 |
Sul | 3 | 150 | 450 |
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]
| Regiao | sem_calc | com_calc |
|---|---|---|
Norte | 800 | 350 |
Sul | 800 | 450 |
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
- CALCULATE transforma a linha atual em filtro. Em uma coluna calculada ou dentro de ADDCOLUMNS, uma soma sem CALCULATE soma a tabela inteira, como o exemplo mostra (800 em todas as linhas).
- Um filtro simples como Vendas[Regiao] = "Sul" substitui o filtro que já existe naquela coluna. Não soma os dois.
- ALL tira o filtro, não o dado. Usado como divisor, ele dá o total para calcular a participação, como no exemplo da coluna pct.
- FILTER percorre linhas. Para uma condição simples sobre uma coluna, o filtro booleano direto dentro de CALCULATE é mais curto e, em geral, mais eficiente.
- Os números mostrados aqui têm ponto decimal. No Power BI em português, o resultado aparece com vírgula (por exemplo, 0,4375).
Quando usar
- Calcular o total de um subconjunto (uma região, um período, um produto).
- Calcular participação ou percentual do total, com ALL no divisor.
- Comparar uma linha com o total da sua categoria, com ALLEXCEPT.
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.