Como calcular dia da semana ponderado em DAX: passo a passo
Vamos criar uma medida em DAX que calcula um valor médio ponderado por dia da semana (por exemplo, vendas ponderadas por importância do dia). Isto é útil quando alguns dias têm maior relevância, custo ou impacto no negócio e queres reflectir isso nas análises — por exemplo, se o sábado tem tráfego 50% superior, ou se a segunda‑feira é menos representativa por feriados. A ideia é aplicar pesos por WeekdayNumber e calcular uma média ponderada que substitua a média simples ou o total simples.
Pré‑requisitos
- Power BI Desktop com um modelo simples: tabela FactSales (Date, SalesAmount, Quantity) e tabela Date com coluna WeekdayName e WeekdayNumber (1‑7). Nota: por defeito DAX WEEKDAY devolve 1=Domingo; ajusta conforme o teu calendário se usares 1=Segunda).
- Conhecimento básico de medidas em DAX, relações entre tabelas e funções como SUMX, VALUES e LOOKUPVALUE.
- Objectivo: criar uma medida WeightedSalesByWeekday em DAX que reflita pesos atribuídos a cada dia da semana.
Passo 1: Definir a tabela de pesos por dia da semana
Precisamos de uma tabela que associe cada dia da semana a um peso (por exemplo, seg=1, sáb=1.5). Podes criar uma tabela calculada em DAX ou carregar uma tabela manual via Power Query/CSV. A vantagem do DATATABLE é que fica no modelo e é fácil de alterar. Exemplo com pesos plausíveis: dias úteis 1.0, quinta 1.2, sexta 1.3, sábado 1.5.
WeekdayWeights =
DATATABLE(
"WeekdayNumber", INTEGER,
"Weight", DOUBLE,
{
{1, 1.0}, -- Domingo (ajusta conforme a tua WeekdayNumber)
{2, 1.1}, -- Segunda
{3, 1.0}, -- Terça
{4, 1.0}, -- Quarta
{5, 1.2}, -- Quinta
{6, 1.3}, -- Sexta
{7, 1.5} -- Sábado
}
)
Passo 2: Garantir relação entre Date e WeekdayWeights
Se a tua tabela Date tem WeekdayNumber, cria uma relação entre Date[WeekdayNumber] e WeekdayWeights[WeekdayNumber]. Isto permite filtrar por dia da semana e usar RELATED ou regras de contexto de filtro. Sem relação, terás de usar LOOKUPVALUE com cuidado, o que pode afectar a performance. Confirma também que a granularidade da tabela Date cobre todo o período de FactSales (por exemplo, 3 anos = ~1 095 linhas).
Passo 3: Medida básica de vendas
Criar uma medida simples para usar como base: SalesAmountTotal. É a referência para comparar o resultado ponderado com o total não ponderado.
SalesAmountTotal = SUM(FactSales[SalesAmount])
Passo 4: Medida de peso aplicado por linha de venda (opcional)
Se tiveres granularidade na fact table com a data da venda, podes obter o peso usando RELATED através da relação Date → WeekdayWeights (ou via LOOKUPVALUE se não houver relação). Isto permite ver, linha a linha, qual o Weight aplicado. Útil para debugging e validação: por exemplo, se uma venda a 2026‑08‑07 (sábado) tiver peso 1.5.
SaleWeight =
VAR wd = RELATED('Date'[WeekdayNumber])
RETURN
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], wd)
Passo 5: Criar a medida WeightedSalesByWeekday (exemplo recomendado)
A medida que interessa é o somatório das vendas multiplicadas pelo peso, dividido pela soma dos pesos (média ponderada). Usamos CALCULATE e SUMX para iterar pelos dias na tabela Date visível no contexto atual. Isto garante que filtros por período ou por produto são respeitados.
WeightedSalesByWeekday =
VAR VisibleDays = VALUES('Date'[Date])
VAR Numerator =
SUMX(
VisibleDays,
CALCULATE(SUM(FactSales[SalesAmount])) *
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], MAX('Date'[WeekdayNumber]))
)
VAR Denominator =
SUMX(
VisibleDays,
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], MAX('Date'[WeekdayNumber]))
)
RETURN
IF(Denominator = 0, BLANK(), Numerator / Denominator)
Exemplo concreto: se num período tiveste 7 dias com vendas diárias [100, 120, 80, 90, 110, 200, 150] e pesos [1,1.1,1,1,1.2,1.3,1.5], o Numerator será a soma de cada venda*peso (~100*1 + 120*1.1 + ... = ~1 204) e o Denominator a soma dos pesos (~8.1), resultando numa média ponderada ~148.6 em vez da média simples ~120. Uma diferença significativa que mostra o impacto do peso do fim‑de‑semana.
Passo 6: Versão alternativa por agregação por Weekday
Uma abordagem mais eficiente agrega primeiro por WeekdayNumber e depois aplica os pesos. Útil para grandes volumes onde iterar por cada dia individual é custoso. Aqui agregas vendas por Weekday e multiplicas pelos pesos, reduzindo chamadas a LOOKUPVALUE.
WeightedSalesByWeekday_Agg =
VAR AggByWeekday =
SUMMARIZE(
'Date',
'Date'[WeekdayNumber],
"SalesPerDay", CALCULATE(SUM(FactSales[SalesAmount]))
)
VAR Numerator =
SUMX(
AggByWeekday,
[SalesPerDay] *
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], 'Date'[WeekdayNumber])
)
VAR Denominator =
SUMX(
AggByWeekday,
LOOKUPVALUE(WeekdayWeights[Weight], WeekdayWeights[WeekdayNumber], 'Date'[WeekdayNumber])
)
RETURN
IF(Denominator = 0, BLANK(), Numerator / Denominator)
Verificar o resultado
Coloca as medidas WeightedSalesByWeekday e SalesAmountTotal num visual (tabela ou cartão) e testa por filtros de período e por WeekdayName. Verifica casos conhecidos: se todos os pesos forem 1, a medida deve igualar SalesAmountTotal; se um dia tiver peso maior, esse dia deve influenciar mais o resultado. Testa também com filtros por hora/loja para garantir que a granularidade da Date corresponde à FactSales.
Conclusão
Com estas medidas consegues analisar vendas (ou qualquer métrica) ajustada por pesos de dia da semana — útil em operações, staffing ou análise sazonal. Próximos passos: parametrizar os pesos com um What‑if parameter para ajustar interactivamente, ou permitir edição via Power Query. Dica final: evita usar LOOKUPVALUE dentro de loops muito grandes sem necessidade; a versão agregada tende a ser mais eficiente em modelos com centenas de milhares de registos.