(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como calcular tempo médio de resolução em DAX: passo a passo

João Barros 11 de August de 2026 4 min de leitura

Este tutorial mostra como calcular o tempo médio de resolução (em horas ou dias) de tickets em DAX — útil para avaliar SLA e desempenho de suporte. Vamos explicar por que usar medidas em vez de colunas calculadas e dar um exemplo prático com variáveis, tratamento de valores em falta e sugestões para validar os resultados no modelo.

Pré-requisitos

  • Power BI Desktop ou outro cliente que suporte DAX.
  • Modelo com uma tabela de factos chamada Tickets contendo as colunas code TicketID, code CreatedDate, code ResolvedDate e code Status.
  • Tabela de datas Date com coluna code Date marcada como Date Table. Ter uma Date Table permite filtrar por mês, trimestre e calcular correctamente totais acumulados.
  • Volume de dados exemplificativo: se tiver 10 000 tickets, as medidas abaixo serão rápidas; em 1 000 000 de linhas convém testar desempenho e usar agregações.

Passo 1: Entender por que usar medida e não coluna

Uma coluna calculada gera um valor por linha no momento da actualização e aumenta o tamanho do modelo. Por exemplo, uma coluna adicional com um número que ocupa 8 a 16 bytes por linha numa tabela de 1 000 000 de linhas pode consumir 8 a 16 MB adicionais, e mais em metadados. Além disso, uma coluna é estática e não reage ao contexto de filtro num visual.

Uma medida calcula dinamicamente no contexto visual. Para tempo médio de resolução queremos flexibilidade: filtrar por período, equipa, prioridade ou status e ver como a média muda. Por isso usamos medidas — menos armazenamento e mais flexibilidade.

Passo 2: Calcular a diferença de tempo básica (horas)

Vamos criar uma medida que calcula a diferença entre ResolvedDate e CreatedDate em horas. A função DATEDIFF retorna um inteiro quando usamos HOUR, por isso a média será em horas inteiras. Para obter decimais podemos usar DATEDIFF em minutes e dividir por 60.

Explicação do código: filtramos Tickets para excluir linhas com datas em falta ou mal formadas, e garantimos ResolvedDate maior ou igual a CreatedDate. Depois usamos AVERAGEX sobre esse conjunto.

Avg Resolution Hours =
VAR ResolvedTickets =
    FILTER(
        Tickets,
        NOT(ISBLANK(Tickets[ResolvedDate]))
            && NOT(ISBLANK(Tickets[CreatedDate]))
            && Tickets[ResolvedDate] >= Tickets[CreatedDate]
    )
RETURN
    AVERAGEX(
        ResolvedTickets,
        DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], HOUR)
    )

Se quiser precisão decimal a nível de minutos, use:

Avg Resolution Hours Precise =
VAR Resolved =
    FILTER(
        Tickets,
        NOT(ISBLANK(Tickets[ResolvedDate]))
            && NOT(ISBLANK(Tickets[CreatedDate]))
            && Tickets[ResolvedDate] >= Tickets[CreatedDate]
    )
RETURN
    AVERAGEX(Resolved, DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], MINUTE) / 60)

Exemplo numérico: num conjunto de 10 000 tickets resolvidos, se a soma das diferenças em horas for 52 000, a média será 5,2 horas por ticket.

Passo 3: Tratar outliers e valores extremos

Outliers podem distorcer a média. Por exemplo, se 1% dos tickets demorou 365 dias a resolver, a média sobe muito. Uma abordagem simples é excluir durações acima de um limite razoável, por exemplo 90 dias. Em 10 000 tickets, 90 dias = 2160 horas; se 200 tickets excederem esse limite, estamos a excluir 2% dos casos.

Avg Resolution Hours (Trimmed) =
VAR MaxHours = 90 * 24
VAR ResolvedTickets =
    FILTER(
        Tickets,
        NOT(ISBLANK(Tickets[ResolvedDate]))
            && NOT(ISBLANK(Tickets[CreatedDate]))
            && Tickets[ResolvedDate] >= Tickets[CreatedDate]
            && DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], HOUR) <= MaxHours
    )
RETURN
    IF(
        COUNTROWS(ResolvedTickets)=0,
        BLANK(),
        AVERAGEX(ResolvedTickets, DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], HOUR))
    )

Alternativas: usar medianas para uma medida robusta ou calcular percentis como 90th percentile para compreender a distribuição. Verifique sempre quantas linhas foram excluídas com uma medida de contagem para confirmar que o corte não remove demasiado dado legítimo.

Passo 4: Média ponderada por prioridade (opcional)

Se quiser dar mais peso a tickets de alta prioridade, use uma média ponderada. Assumimos uma coluna Priority com valores numéricos 1 a 5. Isto faz sentido se, por exemplo, um ticket Priority 5 for três vezes mais crítico que Priority 1.

Weighted Avg Resolution Hours =
VAR Resolved =
    FILTER(
        Tickets,
        NOT(ISBLANK(Tickets[ResolvedDate]))
            && NOT(ISBLANK(Tickets[CreatedDate]))
            && Tickets[ResolvedDate] >= Tickets[CreatedDate]
    )
VAR SumWeighted =
    SUMX(
        Resolved,
        DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], HOUR) * COALESCE(Tickets[Priority],1)
    )
VAR SumWeights =
    SUMX(Resolved, COALESCE(Tickets[Priority],1))
RETURN
    DIVIDE(SumWeighted, SumWeights)

Se Priority for texto (High, Medium, Low), converta antes com SWITCH ou crie uma coluna de mapeamento.

Passo 5: Mostrar em dias e formatar para o utilizador

Para mostrar o resultado em dias com uma casa decimal converta horas para dias. No Power BI, defina o formato da medida para Mostrar como Número com 1 casa decimal.

Avg Resolution Days =
VAR Hours = [Avg Resolution Hours]
RETURN
    IF(ISBLANK(Hours), BLANK(), Hours / 24)

Se preferir hh:mm mostre horas inteiras e minutos com INT e MOD ou use FORMAT para formatar string mas evite FORMAT em indicadores que serão usados em cálculos.

Verificar o resultado

Crie uma visualização de cartão ou tabela com as medidas: code Avg Resolution Hours, code Avg Resolution Hours (Trimmed) e code Avg Resolution Days. Filtre por mês ou equipa para confirmar que os valores mudam conforme esperado. Compare com uma tabela de amostra de 50 tickets: calcule manualmente alguns exemplos para validar a média.

Medidas úteis para validação:

Resolved Count =
CALCULATE(COUNTROWS(Tickets), NOT(ISBLANK(Tickets[ResolvedDate])))

Trimmed Count =
CALCULATE(
    COUNTROWS(Tickets),
    NOT(ISBLANK(Tickets[ResolvedDate])),
    DATEDIFF(Tickets[CreatedDate], Tickets[ResolvedDate], HOUR) <= 90*24
)

Verifique que Resolved Count e Trimmed Count fazem sentido e que o número excluído é plausível (por exemplo 1-5% dependendo do histórico).

Conclusão

Agora sabe calcular o tempo médio de resolução em DAX, tratar outliers e aplicar ponderação por prioridade. Próximos passos recomendados: calcular percentis (p.ex. 90th percentile) para compreender a cauda da distribuição, criar uma medida para a percentagem de tickets dentro do SLA e assegurar que as datas estão num fuso horário consistente antes de calcular durações. Dica de performance: use variáveis, evite iteradores desnecessários em grandes tabelas e pré-aggregate quando possível para modelos com milhões de linhas.