Rolling 12 Months Average em DAX Computing a média de 12 meses em DAX parece uma tarefa simples, mas esconde alguma complexidade. Este artigo explica como escrever a melhor fórmula evitando armadilhas comuns usando funções de inteligência de tempo. Começamos com o modelo usual de dados AdventureWorks, com produtos, vendas e tabela de calendário. O Calendário foi marcado como uma tabela de calendário (é necessário trabalhar com qualquer função de inteligência de tempo) e nós construímos uma hierarquia simples ano-mês-data. Com esta configuração, é muito fácil criar uma primeira tabela dinâmica mostrando vendas ao longo do tempo: ao fazer análise de tendências, se as vendas estiverem sujeitas à sazonalidade ou, em geral, se desejar remover o efeito de picos e queda nas vendas, A técnica comum é a de calcular o valor em um determinado período, geralmente 12 meses, e a média. A média móvel em 12 meses fornece um indicador suave da tendência e é muito útil em gráficos. Dado uma data, podemos calcular a média móvel de 12 meses com esta fórmula, que ainda possui alguns problemas que resolveremos mais tarde: O comportamento da fórmula é simples: calcula o valor das Vendas depois de criar um filtro no calendário que Mostra exatamente um ano completo de dados. O núcleo da fórmula é o DATESBETWEEN, que retorna um conjunto inclusivo de datas entre os dois limites. O menor é: lendo-o do mais íntimo: se mostramos dados por um mês, digamos, julho de 2007, tomamos a última data visível usando LASTDATE, que retorna o último dia em julho de 2007. Então usamos NEXTDAY para tomar o primeiro De agosto de 2007 e finalmente usamos o SAMEPERIODLASTYEAR para retornar um ano, produzindo 1 de agosto de 2006. O limite superior é simplesmente LASTDATE, ou seja, final de julho de 2007. Se usarmos esta fórmula em uma tabela dinâmica, o resultado parece ser bom, mas nós Tem um problema para a última data: de fato, como você pode ver na figura, o valor é calculado corretamente até 2008. Então, não há valor em 2009 (o que é correto, não temos vendas em 2009), mas existe Um valor surpreendente em dezembro de 2010, onde nossa fórmula mostra o grande total em vez de um valor em branco, como seria de esperar. De fato, em dezembro, LASTDATE retorna o último dia do ano e NEXTDAY deve retornar o 1 de janeiro de 2017. Mas NEXTDAY é uma função de inteligência do tempo e espera-se que retornem conjuntos de datas existentes. Este fato não é muito evidente e vale mais algumas palavras. As funções de inteligência do tempo não executam matemática nas datas. Se você quiser tomar o dia após uma determinada data, você pode simplesmente adicionar 1 a qualquer coluna de data e o resultado será no dia seguinte. Em vez disso, as funções de inteligência do tempo mudam os conjuntos de datas de ida e volta ao longo do tempo. Assim, NEXTDAY adquire a sua entrada (no nosso caso uma tabela de uma única linha com o 31 de dezembro de 2010) e desloca-a um dia depois. O problema é que o resultado deve ser 1 de janeiro de 2017, mas, porque a tabela do Calendário não contém essa data, o resultado é BLANK. Assim, nossa expressão calcula as vendas com um limite inferior em branco, o que significa o início dos tempos, resultando como resultado do grande total de vendas. Para corrigir a fórmula, basta alterar a ordem de avaliação do limite inferior: como você pode ver, agora NEXTDAY é chamado após a mudança de um ano de volta. Desta forma, tomamos 31 de dezembro de 2010, movê-lo para 31 de dezembro de 2009 e levamos no dia seguinte, que é 1 de janeiro de 2010: uma data existente na tabela do calendário. O resultado é agora o esperado: neste ponto, precisamos apenas dividir esse número em 12 para obter a média móvel. Mas, como você pode facilmente imaginar, nem sempre podemos dividi-lo por 12. De fato, no início do período não há 12 meses para agregar, mas um número menor. Precisamos calcular o número de meses para os quais há vendas. Isso pode ser feito usando a filtragem cruzada da tabela do calendário com a tabela de vendas depois que aplicamos o novo contexto de 12 meses. Definimos uma nova medida que calcula o número de meses existentes no período de 12 meses: você pode ver na próxima figura que a medida Months12M calcula um valor correto: Vale ressaltar que a fórmula não funciona se você escolher um período Mais de 12 meses, porque o CalendarMonthName possui apenas 12 valores. Se você precisar de períodos mais longos, você precisará usar uma coluna YYYYMM para poder contar mais de 12. A parte interessante desta fórmula que usa filtragem cruzada é o fato de que ele calcula o número de meses disponíveis mesmo quando você filtra usando outro atributos. Se, por exemplo, você selecionar a cor azul usando um slicer, então as vendas começam em julho de 2007 (não em 2005, como acontece com muitas outras cores). Usando o filtro cruzado em Vendas, a fórmula calcula corretamente que, em julho de 2007, há um único mês de vendas disponíveis para o Blue: neste ponto, a média móvel é apenas um DIVIDE: quando usamos isso em uma tabela dinâmica, nós ainda Tem um pequeno problema: de fato, o valor é calculado também por meses para os quais não há vendas (ou seja, meses futuros): isso pode ser resolvido usando uma declaração IF para evitar que a fórmula mostre valores quando não há vendas. Eu não tenho nada contra IF, mas, para o viciado em desempenho entre você, sempre vale a pena lembrar que IF pode ser um assassino do desempenho, porque poderia forçar o mecanismo de fórmula DAX a entrar. Neste caso específico, a diferença é insignificante, mas , Como regra geral, a melhor maneira de remover o valor quando não há vendas é confiar em fórmulas de mecanismo de armazenamento puro como esta: Comparando um gráfico usando o Avg12M com outro que mostra as vendas, você pode facilmente apreciar como a média móvel Descreve as tendências de uma maneira muito mais limpa: Mantenha-me informado sobre os próximos artigos (boletim informativo). Desmarque para baixar livremente o arquivo. SQL Server Denali PowerPivot Alberto Ferrari já escreveu sobre o cálculo de médias móveis em DAX usando uma coluna calculada. Gostaria de apresentar uma abordagem diferente aqui usando uma medida calculada. Para a média móvel, calculo uma média móvel diária (nos últimos 30 dias) aqui. Para o meu exemplo, estou usando a pasta de trabalho PowerPivot que pode ser baixada como parte dos Projetos de Modelos Tabulares do SSAS das amostras do Denali CTP 3. Nesta publicação, estou desenvolvendo a fórmula passo a passo. No entanto, se você estiver com pressa, você pode querer diretamente para os resultados finais abaixo. Com o ano de calendário de 2003 no filtro, a data em colunas e o valor das vendas (da tabela de Vendas na Internet) nos detalhes, os dados da amostra se parecem com isto: Em cada contexto de linhas, a expressão 8216DateDate fornece o contexto atual, ou seja, a data dessa linha . Mas, a partir de uma medida calculada, não podemos referir esta expressão (como não existe uma linha atual para a tabela Data), em vez disso, temos que usar uma expressão como LastDate (8216DateDate). Então, para obter os últimos trinta dias, podemos usar essa expressão. Agora podemos resumir nossas vendas na internet para cada um desses dias usando a função de resumo: Resumir (DatasInPeriod (8216DateDate, LastDate (8216DateDate), - 30, DIA), 8217DateDate 8220SalesAmountSum8221. Sum (8216Internet SalesSales Amount)) E, finalmente, estavam usando a função DAX AverageX para calcular a média desses 30 valores: Quantidade de Vendas (30d avg): AverageX (Resumir (DatasInPeriod (8216DateDate, LastDate (8216DateDate), - 30, DIA), 8217DateDate. 8220SalesAmountSum8221. Soma (8216Internet SalesSales Amount)), SalesAmountSum) Este é o cálculo que estamos usando na nossa tabela de vendas da Internet, conforme mostrado na captura de tela abaixo: Ao adicionar este cálculo à tabela dinâmica a partir de cima, O resultado parece assim: olhando o resultado, parece que não temos dados antes de 1º de janeiro de 2003: o primeiro valor para a média móvel é idêntico ao valor do dia (não há linhas anteriores a essa data). O segundo valor para a média móvel é na verdade a média dos dois primeiros dias e assim por diante. Isso não é bastante correto, mas estou voltando a esse problema em um segundo. A captura de tela mostra o cálculo da média móvel em 31 de janeiro como a média dos valores diários de 2 a 31 de janeiro. Nossa medida calculada também funciona bem quando os filtros são aplicados. Na captura de tela a seguir, usei duas categorias de produtos para a série de dados: como nossa medida calculada funciona em níveis de agregação mais altos. Para descobrir, estou usando a hierarquia do Calendário nas linhas (em vez da data). Por simplicidade, removi o semestre e o quarto dos níveis usando as opções da tabela dinâmica Excels (opção ShowHide fields). Como você pode ver, o cálculo ainda funciona bem. Aqui, o agregado mensal é a média móvel para o último dia do mês específico. Você pode ver isso claramente em janeiro (valor de 14,215.01 também aparece na captura de tela acima como valor para 31 de janeiro). Se este fosse o requisito de negócios (o que parece razoável para uma média diária), a agregação funciona bem em um nível mensal (caso contrário, teremos que ajustar nosso cálculo e este será um tópico da próxima publicação). Mas, embora a agregação faça sentido em um nível mensal, se expandimos essa visão para o nível do dia, veremos que nossa medida calculada simplesmente retorna o valor das vendas para esse dia, e não a média dos últimos 30 dias. Como isso pode ser. O problema resulta do contexto em que calculamos a nossa soma, como destacado no seguinte código: Valor de Vendas (30d avg): AverageX (Resumir (datasinperiod (8216DateDate, LastDate (8216DateDate), - 30, DIA), 8217DateDate. 8220SalesAmountSum8221. Soma (8216Internet SalesSales Amount)), SalesAmountSum) Uma vez que avaliamos essa expressão durante o período de datas determinado, o único contexto que é substituído aqui é 8216DateDate. Em nossa hierarquia, utilizamos diferentes atributos de nossa dimensão (Ano Calendário, Mês e Dia do Mês). Como esse contexto ainda está presente, o cálculo também é filtrado por esses atributos. E isso explica por que o contexto dos dias atuais ainda está presente para cada linha. Para deixar as coisas claras, enquanto avaliamos essa expressão fora do contexto de uma data, tudo está bem como a seguinte consulta DAX mostra quando foi executada pelo Management Studio na perspectiva de vendas na Internet do nosso modelo (usando o banco de dados tabular com os mesmos dados ): Avaliar (resumir (datasinperíodo (8216DateDate, data (2003,1,1), - 5, DIA), 8217DateDate. 8220SalesAmountSum8221. Soma (8216Internet SalesSales Amount))) Aqui, reduzi o período de tempo para 5 dias e também configurou Uma data fixa como LastDate () resultaria na última data da tabela de dimensão da minha data para a qual nenhum dado está presente nos dados de amostra. Aqui está o resultado da consulta: No entanto, depois de configurar um filtro para 2003, nenhuma linha de dados fora de 2003 será incluída na soma. Isso explica a observação acima: parecia que só temos dados a partir de 1º de janeiro de 2003. E agora, sabemos o porquê: o ano de 2003 estava no filtro (como você pode ver na primeira captura de tela desta postagem) e Portanto, estava presente ao calcular a soma. Agora, tudo o que temos a fazer é se livrar desses filtros adicionais porque já estavam filtrando nossos resultados por Data. A maneira mais fácil de fazer isso é usar a função Calcular e aplicar ALL () para todos os atributos para os quais queremos remover o filtro. Como temos alguns desses atributos (Ano, Mês, Dia, Dia da semana) e queremos remover o filtro de todos eles, mas o atributo de data, a função de atalho ALLEXCEPT é muito útil aqui. Se você tiver um fundo MDX, você vai se perguntar por que não temos um problema semelhante ao usar SSAS no modo OLAP (BISM Multidimensional). A razão é que o nosso banco de dados OLAP tem relações de atributos, então, depois de definir o atributo data (chave), os outros atributos também são alterados automaticamente e não precisamos cuidar disso (veja minha postagem aqui). Mas no modelo tabular não temos relações de atributos (nem mesmo um verdadeiro atributo de chave) e, portanto, precisamos eliminar filtros indesejados de nossos cálculos. Então, aqui estamos com o Valor de Vendas (30d avg): AverageX (Summarize (datasinperiod (8216DateDate, LastDate (8216DateDate), - 30, DAY), 8217DateDate. 8220SalesAmountSum8221. Calcule (Sum (8216Internet SalesSales Amount), ALLEXCEPT (8216Date8217,8217DateDate ))), SalesAmountSum) E esta é a nossa tabela dinâmica final no Excel: para ilustrar a média móvel, aqui é o mesmo extrato de dados em uma vista de gráfico (Excel): embora filtrássemos nossos dados em 2003, a média móvel para o primeiro 29 dias de 2003 corretamente leva em conta os dias correspondentes de 2002. Você reconhecerá os valores dos 30 e 31 de janeiro de nossa primeira abordagem, pois foram os primeiros dias para os quais nosso primeiro cálculo teve uma quantidade suficiente de dados (30 dias completos).
No comments:
Post a Comment