Period-over-Period Berechnungen in Power BI Teil 1: DAX-Pattern für YoY, QoQ, MoM und DoD

KPIs in einer Scorecard werden idR mit dem Wert der laufenden Periode sowie dessen prozentualer und/oder absoluter Veränderung zur vorangegangenen Vergleichsperiode dargestellt. Die Ermittlung dieser Period-over-Period Veränderungen ist daher essentielle Voraussetzung für den Betrieb einer Scorecard.

In diesem ersten Teil der Blogserie wird gezeigt, wie die Standardberechnungen in Power BI für Year-over-Year (YoY), Quarter-over-Quarter (QoQ)Month-over-Month (MoM) und Day-over-Day (DoD) mit etwas DAX Know-How verfeinert und zu einem Period-over-Period Measure integriert werden können.

Die hier vorgestellten DAX-Funktionen können wiederum auch in SQL Server Tabular Model und Excel Power Pivot verwendet werden.

------------------------------------------------------------------------------------------------------------------

Updateinformation: Dieser Blogbeitrag wurde am 14.05.2023 aktualisiert.

------------------------------------------------------------------------------------------------------------------

Übersicht zur Blogserie

Teil 1: DAX-Pattern für Period-over-Period Berechnungen
Teil 2: DAX-Pattern für Week-over-Week Berechnungen
Teil 3: DAX-Pattern für Period-over-Period Berechnungen bei relativem Zeitfilter

1. Begriffsdefinitionen

Die Begriffe Year-over-Year, Quarter-over-Quarter und Month-over-Month kommen aus der Investment- und Analystensprache und wurden von dort in das Dashboarding übernommen:

  • YoY ist die Veränderung eines abgeschlossenen Jahres zum Vorjahr sowie die Veränderung eines abgeschlossenen Quartals oder Monats zum gleichen Quartal oder Monat des Vorjahres
    "YOY comparisons are a popular and effective way to evaluate the financial performance of a company and the performance of investments. Any measurable event that repeats annually can be compared on a YOY basis. Common YOY comparisons include annual, quarterly and monthly performance."
    Quelle: www.investopedia.com/terms/y/year-over-year
  • QoQ ist die Veränderung eines Quartals  zum vorhergehenden Quartal
  • MoM ist die Veränderung eines Monats zum vorhergehenden Monat
    "Quarter over quarter (Q/Q) is a rate of change of performance between one fiscal quarter and the previous quarter ... Other variations of the quarter over quarter are the month over month (M/M) and year over year (Y/Y). The month over month measures growth over previous months, but tends to be more volatile than Q/Q, as the rate of change is affected by one-time events, such as natural disasters. The year over year reports changes in performance in one year over a previous year. Y/Y incorporates more data and, thus, is able to give a better long-term picture of the underlying report figure. Q/Q rate of change is typically more volatile than Y/Y measurement, but less volatile than the M/M figure."
    Quelle: www.investopedia.com/terms/q/quarter-over-quarter
  • Gemeinsam ist allen Definitionen, daß sie sich auf abgeschlossene Perioden beziehen (bspw. most recent quarter). In der Regel beziehen sie sich auf Einzelperioden (Monate, Quartale), year-to-date Betrachtungen sind eher die Ausnahme.

Im Controlling werden anstelle des Begriffs YoY viel häufiger die Begriffe ACT-LYACT-PY oder Variance Actual/Prior Year verwendet. Dazu ist im Controlling die year-to-date Betrachtung auf Quartals- und Monatsebene die Regel und nicht die Ausnahme.

2. Ausgangssituation

Wir verwenden die Faktentabelle Fact InternetSales aus der Adventure Works Demodatenbank sowie die manuell erstellte Datumsdimension Dim Datum. Der disconnected Measure Table dient lediglich zur Aufnahme des vorerst einzigen Measures:

Sales = 
Sum('Fact InternetSales'[SalesAmount])

Die Datumsdimension ist von zentraler Bedeutung für die Period-over-Period Berechnungen. Einerseits muß diese Tabelle als Date Dimension im Datenmodell deklariert sein, damit die Time Intelligence Funktion der DAX-Formelsprache genutzt werden können. Andererseits benötigen wir für die Verfeinerung der Berechnungen jeweils für das Jahr, das Quartal und das Monat eine Spalte, welche die Periode als jahresspezifische Zahl abbildet:

3. Ermittlung der Period-over-Period Veränderungen mittels Quick Measures

Power BI bietet in den sogenannten Quick Measures jeweils eine Option für YoY, QoQ und MoM:

Die Konfiguration ist sehr simpel: neben unserem Basis-Measure Sales wird lediglich die Datumsspalte aus der als Date Dimension deklarierten Tabelle benötigt. Mit dem Parameter Number of Periods wird festgelegt, wieviele Perioden (hier: Monate) für den Vergleich zurückgegangen werden soll:

Die Measures werden vom Wizard automatisch angelegt, hier die (lediglich geringfügig nachbearbeiteten) DAX-Statements:

Sales MoM% (Quick M) = 
VAR 
    PREV_MONTH = CALCULATE([Sales]; DATEADD('Dim Datum'[Datum]; -1; MONTH))
RETURN
	DIVIDE([Sales] - PREV_MONTH; PREV_MONTH)
Sales QoQ% (Quick M) = 
VAR 
    PREV_QUARTER = CALCULATE([Sales]; DATEADD('Dim Datum'[Datum]; -1; QUARTER))
RETURN
	DIVIDE([Sales] - PREV_QUARTER; PREV_QUARTER)
Sales YoY% (Quick M) = 
VAR 
    PREV_YEAR = CALCULATE([Sales]; DATEADD('Dim Datum'[Datum]; -1; YEAR))
RETURN
	DIVIDE([Sales] - PREV_YEAR; PREV_YEAR)

oder

Sales YoY% (Quick M) = 
VAR 
    PREV_YEAR = CALCULATE([Sales]; SAMEPERIODLASTYEAR('Dim Datum'[Datum]))
RETURN
	DIVIDE([Sales] - PREV_YEAR; PREV_YEAR)

Wie zu sehen ist, beruht die Period-over-Period Berechnung auf der Verwendung der DAX-Funktion DATEADD, diese liefert für eine bestimmte Periode die gewünschte zeitversetzte Periode über die Parameter DAY, MONTHQUARTER oder YEAR:

Für die YoY Berechnung kann alternativ auch die DAX-Funktion SAMEPERIODLASTYEAR als "Syntax Sugar" verwendet werden. Die DAX-Funktionen PREVIOUS (Day, Month, Quarter, Year) sowie PARALLELPERIOD (Month, Quarter, Year) sind verwandt, haben aber ein abweichendes Verhalten auf den verschiedenen Zeitebenen und werden weiter unter im direkten Vergleich betrachtet.

Die Berechnungsergebnisse können am effektivsten mit dem Matrix Visual auf der Zeitachse plausibilisiert werden:

Bei näherer Betrachtung fällt aber auf, daß einige Berechnungsergebnisse schwer zu erklären sind. Daher ist es vorerst empfehlenswert, Hilfs-Measures mit den verwendeten Bezugswerten der jeweiligen Vorperiode anzulegen (diese können ganz einfach durch Kopieren und Kürzen des DAX-Codes aus den Quick Measures erstellt werden):

Sales MoM Last Month (Quick M) = 
    CALCULATE(
        [Sales]; 
        DATEADD('Dim Datum'[Datum]; -1; MONTH)
    )
Sales QoQ Last Quarter (Quick M) = 
    CALCULATE(
        [Sales]; 
        DATEADD('Dim Datum'[Datum]; -1; QUARTER)
    )
Sales YoY Last Year (Quick M) = 
    CALCULATE(
        [Sales]; 
        DATEADD('Dim Datum'[Datum]; -1; YEAR)
    )

Jetzt können anhand der ermittelten Vorperioden-Werte folgende wichtige Schlüsse für die Praxis gezogen werden:

  1. Alle DATEADD() Berechnungen handhaben die ersten Perioden auf der Zeitachse automatisch richtig. Solange kein Vorperiodenwert ermittelt werden kann, findet auch keine Berechnung statt. Beim Erreichen der letzten bebuchten (= aktuellen) Periode endet die Berechnung allerdings nicht automatisch sondern läuft weiter bis zum Ende des Kalenderjahres/-quartals/-monats/-tags.
  2. Für die Ermittlung der Period-over-Period Veränderung muß die Berechnung auf den sinnvollen Zeitraum mit verfügbaren Werten sowohl beim Perioden- als auch beim Vorperiodenwert limitiert werden.
  3. Die Berechnung mit DATEADD() ergibt grundsätzlich von der "korrespondierenden Ebene" abwärts Sinn, nicht aber aufwärts.
    d.h. Last Year macht Sinn auf Jahres-, Quartals-, Monats- und Tagesebene
    d.h. Last Quarter macht Sinn auf Quartals-, Monats- und Tagesebene, nicht aber auf Jahresebene (allerdings ist der Vergleich zum Vorquartalsmonat oder Vorquartalstag unüblich und ist dann jedenfalls erklärungsbedürftig)
    d.h. Last Month macht Sinn auf Monats- und Tagesebene, nicht aber auf Jahres- und Quartalsebene
    d.h. Last Day macht Sinn auf Tagesebene, nicht aber auf Jahres-, Quartals- und Monatsebene

Die Berechnung der Day-over-Day (DoD) Veränderung kann jetzt durch Variation der bereits bekannten Formeln erstellt werden (ein Quick Measure steht nicht zur Verfügung):

Sales DoD Last Day (Basis) = 
    CALCULATE(
        [Sales]; 
        DATEADD('Dim Datum'[Datum]; -1; DAY)
    )
Sales DoD% (Basis) = 
VAR 
    PREV_DAY = CALCULATE([Sales]; DATEADD('Dim Datum'[Datum]; -1; DAY))
RETURN
	DIVIDE([Sales] - PREV_DAY; PREV_DAY)

Wie bereits bei den anderen Measures diskutiert, erfolgt auch hier die Berechnung auf der direkt korrespondierenden Tagesebene einwandfrei, die Berechnung auf den übergeordneten zeitlichen Ebenen ergibt auch hier keinen Sinn und sollte auch hier unterdrückt werden:

4. Optimierung: Limitierung der zeitlichen Berechnung zwischen erster und letzter IST-Buchung

Zur Lösung der ersten Problemzone der Quick Measures legen wir 2 Hilfs-Measures zur Ermittlung des Min- und Max-Datums an, da eine einfache Begrenzung auf bebuchte Perioden in der Praxis nicht ausreicht (wie bereits hier beschrieben). Die DAX-Funktion ALL ist dabei entscheidend, um die Ermittlung unabhängig vom sogenannten Filter Kontext zu machen. Alternativ könnten die beiden Measures auch als Variablen innerhalb der folgenden Measures ermittelt werden, der Nachteil wäre dann aber, daß das gleiche Statement in allen Measures wiederholt werden müßte (da es in DAX bisher keine globalen Variablen gibt):

Info MIN-Date with Facts = 
    CALCULATE(
        MIN('Fact InternetSales'[OrderDate]);
        ALL('Fact InternetSales')
    )
Info MAX-Date with Facts = 
    CALCULATE(
        MAX('Fact InternetSales'[OrderDate]);
        ALL('Fact InternetSales')
    )

Diese beiden Parameter werden in die Berechnungsmeasures wie im folgenden gezeigt eingeknüpft.

5. Optimierung: Beschränkung der Berechnung auf die direkt korrespondierende zeitliche Ebene (also YoY auf Jahr, QoQ auf Quartale und MoM auf Monate)

Zum leichteren Verständnis wird für den Sales Last Month ein eigenes Measures angelegt, um die Berechnungsergebnisse leichter überprüfen zu können. Im Kern wird die bereits aus dem Quick Measure bekannte DAX-Funktion DATEADD verwendet, diese wird jedoch mit einem IF-Statement an die beiden Bedingungen zur "Ermittlung nur auf Monatsebene" (-> DISTINCTCOUNT) und "Ermittlung nur bis zum letzten bebuchten Monat" (-> MAX, gekoppelt mit LOOKUPVALUE, um aus dem MAX-Datum das MAX-Monat nachzuschlagen) geknüpft:

Sales Last Month = 
VAR 
    MonatBebuchtMAX = LOOKUPVALUE('Dim Datum'[Monat mit Jahr (Nr)];'Dim Datum'[Datum];[Info MAX-Date with Facts])
RETURN
    IF(
        DISTINCTCOUNT('Dim Datum'[Monat mit Jahr (Nr)])=1 && DISTINCTCOUNT('Dim Datum'[Datum])>1
        && MAX('Dim Datum'[Monat mit Jahr (Nr)]) <= MonatBebuchtMAX;
        CALCULATE(
            [Sales];
            DATEADD('Dim Datum'[Datum]; -1; MONTH)
            )
        ;BLANK()
        )

Im nächsten Schritt erfolgt die eigentliche MoM-Berechnung, hier braucht es lediglich zusätzlich zur MAX-Bedingung auch eine MIN-Bedingung, damit die Subtraktion im ersten Monat unterbunden wird:

Sales MoM = 
VAR MonatBebuchtMIN = LOOKUPVALUE('Dim Datum'[Monat mit Jahr (Nr)];'Dim Datum'[Datum];[Info MIN-Date with Facts])
VAR MonatBebuchtMAX = LOOKUPVALUE('Dim Datum'[Monat mit Jahr (Nr)];'Dim Datum'[Datum];[Info MAX-Date with Facts])

RETURN
IF(
    MIN('Dim Datum'[Monat mit Jahr (Nr)]) > MonatBebuchtMIN
    && MAX('Dim Datum'[Monat mit Jahr (Nr)]) <= MonatBebuchtMAX
    && DISTINCTCOUNT('Dim Datum'[Monat mit Jahr (Nr)])=1 && DISTINCTCOUNT('Dim Datum'[Datum])>1; 
    [Sales] - [Sales Last Month];
    BLANK()
)

Die Ermittlung der Sales MoM% ist jetzt sehr einfach:

Sales MoM% = 
    Divide(
        [Sales MoM];
        [Sales Last Month]
    )

Hier die fertigen Berechnungsergebnisse der Measures, die Berechnung erfolgt jetzt nur noch auf Monatsebene und endet im letzten bebuchten Monat:

Analog dazu werden jetzt auch die Measures für QoQ und YoY erzeugt. Dabei wird lediglich die Anzahl der benötigten Monate beim DISTINCTCOUNT variiert und die MIN-/MAX-Bedingungen auf das Quartal bzw. das Jahr angewendet:

Sales QoQ = 
VAR QuartalBebuchtMIN = LOOKUPVALUE('Dim Datum'[Quartal mit Jahr (Nr)];'Dim Datum'[Datum];[Info MIN-Date with Facts])
VAR QuartalBebuchtMAX = LOOKUPVALUE('Dim Datum'[Quartal mit Jahr (Nr)];'Dim Datum'[Datum];[Info MAX-Date with Facts])

RETURN
IF(
    MIN('Dim Datum'[Quartal mit Jahr (Nr)]) > QuartalBebuchtMIN
    && MAX('Dim Datum'[Quartal mit Jahr (Nr)]) <= QuartalBebuchtMAX
    && DISTINCTCOUNT('Dim Datum'[Monat mit Jahr (Nr)])=3; 
    [Sales] - [Sales Last Quarter];
    BLANK()
)
Sales YoY = 
VAR JahrBebuchtMIN = LOOKUPVALUE('Dim Datum'[Jahr];'Dim Datum'[Datum];[Info MIN-Date with Facts])
VAR JahrBebuchtMAX = LOOKUPVALUE('Dim Datum'[Jahr];'Dim Datum'[Datum];[Info MAX-Date with Facts])

RETURN
IF(
    Min('Dim Datum'[Jahr]) > JahrBebuchtMIN
    && Max('Dim Datum'[Jahr]) <= JahrBebuchtMAX
    && DISTINCTCOUNT('Dim Datum'[Monat mit Jahr (Nr)])=12; 
    [Sales] - [Sales Last Year];
    BLANK()
)

Die Berechnung erfolgt jetzt für die jeweilige Kennzahl MoM, QoQ und YoY nur auf der direkt korrespondierenden Zeitebene. Es handelt sich also auf jeder Ebene um die Veränderung zur Vorperiode, eine allgemein leicht verständliche Berechnungsart:

Die optimierte Berechnung der DoD erfolgt nach dem gleichen Prinzip:

Sales DoD = 
VAR DatumBebuchtMIN = [Info MIN-Date with Facts]
VAR DatumBebuchtMAX = [Info MAX-Date with Facts]

RETURN
IF(
    MIN('Dim Datum'[Datum]) > DatumBebuchtMIN
    && MAX('Dim Datum'[Datum]) <= DatumBebuchtMAX
    && DISTINCTCOUNT('Dim Datum'[Datum])=1; 
    [Sales] - [Sales Last Day];
    BLANK()
)

Der einzige Nachteil dieser Measures ist, daß bei der Erstellung eines neuen Visuals ein BLANK() angezeigt wird, solange nicht eine gültige zeitliche Periode selektiert wird. Das kann bei einem ungeübten / uninstruierten User leicht den Eindruck erwecken, daß das Measure nicht funktioniert.

Die 3 Measures können jetzt mit einer einfachen Addition zu einem integrierten Period-over-Period Measure zusammengefasst werden:

Sales PoP = [Sales MoM] + [Sales QoQ] + [Sales YoY]
Sales PoP% = [Sales MoM%] + [Sales QoQ%] + [Sales YoY%]

Die Einzel-Measures für die Herleitung können jetzt ausgeblendet (aber nicht gelöscht) werden und Berichte nur noch mit dem PoP-Measure erstellt werden.

6. Vergleich PREVIOUS vs. DATEADD

Die PREVIOUS-Berechnungen liefern auf der direkt korrespondierenden zeitlichen Ebene die gleichen Ergebnisse wie die DATEADD-Funktion, der Unterschied besteht in den Berechnungen auf den über- und untergeordneten zeitlichen Ebenen. Auf übergeordneter Ebene - bspw. auf Quartalsebene in der PREVIOUSMONTH Berechnung - wird der Wert der ersten Periode gezeigt, das ist jedenfalls sinnvoller als die Summe in der DATEADD Berechnung. Auf untergeordneter Ebene - bspw. auf Monatsebene in der PREVIOUSQUARTER Berechnung - wird der Wert der übergeordneten Ebene wiederholt.

Dies ist nützlich für alle Berechnungen, die sich auf die volle Vorperiode beziehen sollen.

Sales DoD Last Day (PreviousDay) = 
    CALCULATE(
        [Sales]; 
        PREVIOUSDAY('Dim Datum'[Datum])
    )
Sales MoM Last Month (PreviousMonth) = 
    CALCULATE(
        [Sales]; 
        PREVIOUSMONTH('Dim Datum'[Datum])
    )
Sales QoQ Last Quarter (PreviousQuarter) = 
    CALCULATE(
        [Sales]; 
        PREVIOUSQUARTER('Dim Datum'[Datum])
    )
Sales YoY Last Year (PreviousYear) = 
    CALCULATE(
        [Sales]; 
        PREVIOUSYEAR('Dim Datum'[Datum])
    )

    Hier das Berechnungsprofil im direkten Vergleich am Beginn des Zeithorizonts des Demodatasets ...

    ... und hier am Ende des Zeithorizonts, die Berechnungen reichen aufgrund der genannten Eigenschaften weiter in die Zukunft:

    7. Vergleich PARALLELPERIOD vs. DATEADD vs. PREVIOUS

    Die DAX-Funktion PARALLELPERIOD liefert ähnliche Ergebnisse wie die DATEADD-Funktion. Der Unterschied besteht darin, daß PARALLELPERIOD - ähnlich wie die PREVIOUS-Funktionen - immer auf die vollständige Vergleichsperiode referenziert. Daher werden nur 3 Berechnungsparameter angeboten, die tagesbezogene Berechnung würde zum gleichen Ergebnis wie die DATEADD-Berechnung führen:

      Sales YoY Last Year (ParallelPeriod) = 
          CALCULATE(
              [Sales]; 
              PARALLELPERIOD('Dim Datum'[Datum]; -1; YEAR)
          )
      Sales YoY Last Quarter (ParallelPeriod) = 
          CALCULATE(
              [Sales]; 
              PARALLELPERIOD('Dim Datum'[Datum]; -1; QUARTER)
          )
      Sales YoY Last Month (ParallelPeriod) = 
          CALCULATE(
              [Sales]; 
              PARALLELPERIOD('Dim Datum'[Datum]; -1; MONTH)
          )

      Wir sehen in unserem Szenario mit ungefilterten Perioden, daß die Funktionen aber auch hier auf den über- bzw. untergeordneten zeitlichen Ebenen abweichende Ergebnisse liefern.

      • "The PARALLELPERIOD function is similar to the DATEADD function except that PARALLELPERIOD always returns full periods at the given granularity level instead of the partial periods that DATEADD returns. For example, if you have a selection of dates that starts at June 10 and finishes at June 21 of the same year, and you want to shift that selection forward by one month then the PARALLELPERIOD function will return all dates from the next month (July 1 to July 31); however, if DATEADD is used instead, then the result will include only dates from July 10 to July 21."
      • Die PARALLELPERIOD-Berechnung mit dem YEAR Parameter liefert die gleichen Ergebnisse wie die PREVIOUSYEAR-Funktion, lediglich auf der TOTAL Ebene wird die Summe aus der DATEADD-Funktion angezeigt.
      • Die PARALLELPERIOD-Berechnung mit dem QUARTER Parameter liefert ebenfalls grundsätzlich die gleichen Ergebnisse wie die PREVIOUSQUARTER-Funktion, aber auch hier werden auf den übergeordneten zeitlichen Ebenen (= Year + Total) die (unerwünschten) Aggregate der DATEADD-Funktion angezeigt.
      • Die PARALLELPERIOD-Berechnung mit dem MONTH Parameter liefert (bei ungefilterten Perioden) die gleichen Ergebnisse wie die DATEADD-Funktion.

      Zusammenfassend läßt sich feststellen, daß die PARALLELPERIOD-Berechnungen sich auf den direkt assozierten zeitlichen Ebenen sowie den darunterliegenden Ebenen verhalten wie die PREVIOUS-Berechnungen (= erwünscht) und auf den übergeordneten Ebenen wie die DATEADD-Berechnung (= unerwünscht). Hier das Berechnungsprofil im direkten Vergleich am Beginn des Zeithorizonts des Demodatasets …

      … und hier am Ende des Zeithorizonts, die Berechnungen reichen wie bei den PREVIOUS Berechnungen weiter in die Zukunft als die DATEADD Berechnungen:

      8. Fazit

      Für die Berechnung der Period-over-Period Veränderungen bei "vollen" (= ungefilterten) Perioden können auf der direkt assozierten Zeitebene gleichermaßen die DATEADD-Funktion, die PREVIOUS-Funktionen oder die PARALLELPERIOD-Funktion verwendet werden.

      Der Unterschied liegt einerseits in den Berechnungsergebnissen auf den über- und untergeordneten Zeitebenen. Dabei liefern die PREVIOUS-Funktionen die intuitivsten Ergebnisse. Die DATEADD-Funktion, die in den Quick Measures verwendet wird, liefert in der YoY-Variante auf allen zeitlichen Ebenen sehr nützliche Ergebnisse. Die QoQ- und MoM-Varianten liefern hingegeben auf den über- und untergeordneten Zeitebenen unserer Einschätzung nach unbrauchbare Ergebnisse. Die Verwendung der PARALLELPERIOD-Funktion bringt in diesem Kontext keine Vorteile, da die Eigenschaften der PREVIOUS- und DATEADD-Funktionen vermischt werden.

      Der Unterschied liegt andererseits in den Berechnungsergebnissen bei gefilterten Perioden, bspw. auf 7 Tage eines Monats. Während die DATEADD-Funktion zum gleichen gefilterten Zeitraum der Vorperiode vergleicht, referenzieren die PREVIOUS- und PARALLELPERIOD-Funktionen auf die vollständige (ungefilterte) Vorperiode.

      Wir empfehlen daher, je nach erwünschtem Verhalten im Einzelfall entweder die DATEADD- oder die PREVIOUS-Funktionen für die Period-over-Period Ermittlung einzusetzen. Wie im Blogbeitrag gezeigt, kann durch Beschränkung der jeweiligen PoP-Berechnung auf die direkt assozierte zeitliche Ebene und anschließendem Zusammenfügen zu einem integrierten PoP-Measure die Ebenenproblematik vollständig ausgeschalten werden. Die Beschränkung der Berechnungen auf den Zeitraum zwischen erster und letzter bebuchter Periode ist nach unserer Einschätzung ebenfalls in allen Syntaxvarianten sinnvoll.

      9. Ausbaupotentiale

      Die "Blanks" in den ersten Perioden sowie auf Jahres- und Total-Ebene könnten noch mit einem sprechenden Text wie "(select valid period)" ausgestattet werden und die WoW-Measures könnten mit einer vollständigen +/- Vorzeichenformatierung ausgestattet werden, wie in diesem Blogbeitrag gezeigt. In beiden Fällen ändert sich das Format des Measures jedoch von Zahl auf Text, was gewisse Folgethemen aufwirft.

      Ein Praxisthema ist die Ermittlung der letzten abgeschlossenen Periode (bspw. das most recent quarter). Eine allgemeingültige Lösung ist dann einfach umzusetzen, wenn es verlässlich an jedem Tag im Jahr Faktendatensätze (bspw. Verkäufe oder Sensordaten) gibt. Alternativ kann mit einem Kennzeichen in der Datumsdimension gearbeitet werden, das jedes Datum als abgeschlossen oder nicht abgeschlossen definiert und woraus der Abschluß eines Monats, eines Quartals oder eines Jahres geschlossen werden kann.

      Weiterführende Quellen

      docs.microsoft.com/en-us/dax/dateadd-function-dax
      docs.microsoft.com/en-us/dax/sameperiodlastyear-function-dax
      docs.microsoft.com/en-us/dax/previousyear-function-dax
      docs.microsoft.com/en-us/dax/previousquarter-function-dax
      docs.microsoft.com/en-us/dax/previousmonth-function-dax
      docs.microsoft.com/en-us/dax/previousday-function-dax
      docs.microsoft.com/en-us/dax/parallelperiod-function-dax

      Über den Autor

      Blog auf Feedly abonnieren

      Kategorien

      Verwandte Beiträge

      Power BI Camp - Präsenztrainings in Wien und Nürnberg!

      Dashboarding mit Power BI, DAX & Datenmodellierung und Power Query. Drei Einzelmodule oder als ganze Trainingswoche - für Einsteiger und Fortgeschrittene!

      Termine 2022

      Wien: (7./8. Februar 2022)
      und 25.-28 April 2022
      Nürnberg: (14./15. Februar 2022)
      und 9.-12. Mai 2022

      Jetzt buchen und Rabatt sichern.

      Jetzt buchen!

      Leave a Replay

      1 Gedanke zu „Period-over-Period Berechnungen in Power BI Teil 1: DAX-Pattern für YoY, QoQ, MoM und DoD“

      1. Sehr geehrter Herr Lochner,

        vielen Dank für ihre ausführliche Erklärung der PoP Berechnung mittels DAX.
        Ich bin auf einen Fehler gestoßen in der Berechnung für die Sales Last Month/Sales MoM.

        In dem IF Argument fehlt eine Condition ob es sich bei der Filterebene um den Tagesebene handelt. Ansonsten wird, wenn man von Monat auf Tag Hierarchie wechselt ab dem zweiten Monat der Vormonat mit addiert in der PoP berechnung.
        Ich habe es bei mir mit einer weiteren AND Bedingung gelöst “DISTINCTCOUNT ( Dim_Datum[Datum] ) > 1”

        Sales Last Month =
        VAR MonatBebuchtMAX =
        LOOKUPVALUE (
        ‘Dim Datum'[Monat mit Jahr (Nr)];
        ‘Dim Datum'[Datum]; [Info MAX-Date with Facts]
        )
        RETURN
        IF (
        DISTINCTCOUNT ( Dim Datum[Datum] ) > 1
        && DISTINCTCOUNT ( ‘Dim Datum'[Monat mit Jahr (Nr)] ) = 1
        && MAX ( ‘Dim Datum'[Monat mit Jahr (Nr)] ) 1
        && MIN ( ‘Dim Datum'[Monat mit Jahr (Nr)] ) > MonatBebuchtMIN
        && MAX ( ‘Dim Datum'[Monat mit Jahr (Nr)] ) <= MonatBebuchtMAX
        && DISTINCTCOUNT ( 'Dim Datum'[Monat mit Jahr (Nr)] ) = 1;
        [Sales] – [Sales Last Month];
        BLANK ()
        )

        Vielleicht könnten sie ja mal überprüfen ob ich mich hier nicht geirrt habe. Vielen Dank für den Tollen Blog!

        Antworten

      Schreibe einen Kommentar zu Lukas Hofer Antworten abbrechen

      Kostenlos zum Newsletter anmelden

      Ihre Anfrage

      Schicken Sie uns Ihre Fragen und Anregungen!