Einführung

Zu meinem letzten Artikel über den Aufbau der Like-for-Like (L4L)-Lösung auf Foundation von Energy Question:

Die Lösung funktioniert größtenteils wie erwartet. Ich habe es meinen Kollegen und einigen Kunden gezeigt.

Das Suggestions struggle positiv, aber ich habe einige Fragen und die Ergebnisse meiner Lösung entsprachen nicht den Erwartungen der fragenden Particular person.

Das Downside

Ich habe bei der Berechnung des PY-Werts ein Downside festgestellt.

Technisch gesehen sind die Ergebnisse korrekt, aus Benutzersicht jedoch nicht.

Sehen Sie sich die folgenden beiden Screenshots an, die zwei verschiedene Fälle zeigen, die die Kennzahlen „Einzelhandelsumsätze“ und „Einzelhandelsumsätze PY“ umfassen. Die Ergebnisse für diese beiden Fälle können das Publikum verwirren.

Versuchen Sie, das Downside zu erkennen, bevor Sie weiterlesen.

Abbildung 1 – Der erste PY-Fall – Vorübergehend geschlossener (Refresh) Laden (Abbildung vom Autor)

Dies ist der erste Fall für die Filiale in Turin, die zwischen März und Juli 2024 vorübergehend geschlossen struggle.

Abbildung 2 – Der zweite PY-Fall – Eine Mischung aus einem vorübergehend geschlossenen und einem schließenden Geschäft (Abbildung vom Autor)

Und hier ist der zweite Fall für den Roma-Retailer, der von August bis Oktober 2023 vorübergehend geschlossen und im August 2024 endgültig geschlossen struggle.

Wir sehen diese Ergebnisse für den zweiten Fall:

  1. Die Werte für den Einzelhandelsumsatz im Vorjahr gelten für „vergleichbare“ Geschäfte, jedoch mit einer Unterbrechung zwischen August und Oktober.
  2. Werte für die Kennzahl „Einzelhandelsumsätze“ für „Nicht vergleichbar – Schließung“-Filialen.
  3. Werte für die Einzelhandelsumsätze-PY-Kennzahl für „Nicht vergleichbar – Auffrischen“-Filialen.

Aus technischer Sicht sind diese Ergebnisse absolut sinnvoll und korrekt.

Die Kennzahlen zeigen die korrekten L4L-Zustände für die aktuelle Periode und das Vorjahr.

Was sind additionally die Probleme?

Für den Benutzer sind sie sehr verwirrend und werden nicht den Erwartungen entsprechen.

Betrachten Sie es aus der Sicht des Benutzers:

Bei der Betrachtung von Ergebnissen für bestimmte L4L-Zustände sollten die beiden Kennzahlen die Ergebnisse demselben L4L-Zustand zuordnen, unabhängig davon, ob sie für die aktuelle Periode oder das Vorjahr berechnet werden.

Dies führt zu einer neuen Komplexität der Lösung.

Die Lösung

Ich benötige eine zweite Spalte für den L4LKey für das Vorjahr.

Für die erste L4LKey-Spalte vergleiche ich die Eröffnungs- und Schlussdaten mit den Monatsdaten des Vorjahres (Einzelheiten finden Sie im ersten Artikel).

Für die zweite L4LKey_PY-Spalte muss ich diese Daten mit den Monatsdaten desselben Jahres vergleichen wie die Eröffnungs- und Schließungsdaten.

Die Idee ist etwas kontraintuitiv, aber sie liefert das Ergebnis, das ich brauche.
Bitte bleiben Sie bei mir, und Sie werden sehen, wie es ausgehen wird

Zuerst habe ich versucht, es in Energy Question zu lösen, wie ich es in der ursprünglichen Lösung getan habe. Aber es hat nicht funktioniert. Zum Grund komme ich gleich.

Dann bin ich dazu übergegangen, die Bridge_L4L-Tabelle in SQL zu erstellen, aber die Ergebnisse waren wieder unbrauchbar, da ich immer doppelte Zeilen für den Rome-Retailer bekam, da ich zwei Zeilen für die beiden L4L-Zustände für diesen Retailer habe:

Abbildung 3 – Zwei Zeilen für die Filiale in Rom (ID 222) für die beiden Jahre 2023 und 2024 (Abbildung vom Autor)

Ich habe jeweils eine Zeile für die vorübergehende Schließung im Jahr 2023 und die endgültige Schließung im Jahr 2024.

Daher gibt der Be part of immer zwei Zeilen zurück, da der Speicherschlüssel dupliziert wird.

Daher entschied ich mich für einen prozeduralen Ansatz.

Ich durchlaufe jede Zeile in der Tabelle mit den Eröffnungs- und Schlussgeschäften und wende die Zustände auf die Tabelle an, die eine Zeile professional Geschäft und Monat enthält.

Ich habe dies erreicht, indem ich temporäre Tabellen in SQL und den folgenden SQL-Code verwendet habe:

-- Declare all wanted variables
DECLARE @StoreKey       int;
DECLARE @OpenDate       date;
DECLARE @CloseDate      date;
DECLARE @L4LKey         int;

-- Create the Cursor to loop via the Shops with every opening, closing, and refresh dates
DECLARE sd CURSOR FOR
    SELECT (StoreKey)
            ,(OpenDate)
            ,(CloseDate)
            ,(L4LKey)
        FROM #tmp_Store_Dates
            -- Order per Time limit, because the process should run from the primary (oldest) to the final (latest) row
            ORDER BY (CloseDate);

OPEN sd;

-- Get the primary row
FETCH NEXT FROM sd INTO @StoreKey, @OpenDate, @CloseDate, @L4LKey;

-- Begin the loop
WHILE @@FETCH_STATUS = 0
BEGIN
    -- Replace all rows in line with every retailer based mostly on the L4L standing and the respective dates, based mostly on the earlier years' dates
    UPDATE (#tmp_Stores_Months)
        SET (OpenDate) = @OpenDate
            ,(CloseDate) = @CloseDate
            ,(L4LKey) = CASE @L4LKey
                            WHEN 2
                                THEN IIF(@OpenDate >= (FirstDayOfMonthPY), @L4LKey, NULL)
                            WHEN 3
                                THEN IIF(@CloseDate <= (LastDayOfMonthPY), @L4LKey, NULL)
                            WHEN 4
                                THEN IIF(@OpenDate >= (FirstDayOfMonthPY) AND @CloseDate <= (LastDayOfMonthPY), @L4LKey, NULL)
                                ELSE 1
                            END
            WHERE (L4LKey) IS NULL
                AND (StoreKey) = @StoreKey;

-- Replace based mostly on the identical month for the PY calculation
UPDATE (#tmp_Stores_Months)
        SET (OpenDate) = @OpenDate
            ,(CloseDate) = @CloseDate
            ,(L4LKey_PY) = CASE @L4LKey
                            WHEN 2
                                THEN IIF(@OpenDate >= (FirstDayOfMonth), @L4LKey, NULL)
                            WHEN 3
                                THEN IIF(@CloseDate <= (LastDayOfMonth), @L4LKey, NULL)
                            WHEN 4
                                THEN IIF(@OpenDate >= (FirstDayOfMonth) AND @CloseDate <= (LastDayOfMonth), @L4LKey, NULL)
                                ELSE 1
                            END
            WHERE (L4LKey_PY) IS NULL
                AND (StoreKey) = @StoreKey;
    
    -- Get the subsequent row till all rows are processed
    FETCH NEXT FROM sd INTO @StoreKey, @OpenDate, @CloseDate, @L4LKey;

END

-- Shut the Cursor
CLOSE sd;
DEALLOCATE sd;

-- Replace the L4LKey and L4LKey_PY in all empty rows
UPDATE #tmp_Stores_Months
    SET (L4LKey) = 1
        WHERE (L4LKey) IS NULL;

UPDATE #tmp_Stores_Months
    SET (L4LKey_PY) = 1
        WHERE (L4LKey_PY) IS NULL;

Das Ergebnis des Verfahrens ist eine Tabelle mit einer Spalte, die die L4L-Zustände basierend auf dem Vorjahr für jeden Monat (L4LKey) und einer Spalte, die die L4L-Zustände basierend auf demselben Jahr für jeden Monat (L4LKey_PY) abbildet, enthält:

Abbildung 4 – Das Ergebnis der Prozedur für die Bridge_L4L-Tabelle mit den beiden L4LKey-Spalten (Abbildung vom Autor)

Der nächste Schritt besteht darin, das Ergebnis dieser Prozedur in Energy BI zu importieren und eine zusätzliche Beziehung zwischen der Bridge_4L- und der DIM_L4L-Tabelle für die neue Spalte L4LKey_PY hinzuzufügen:

Abbildung 5 – Das Datenmodell mit der zusätzlichen L4LKey_PY-Spalte und der zusätzlichen Beziehung zu DIM_L4L (Abbildung vom Autor)

Dadurch kann ich die Berechnung des PJ-Ergebnisses steuern.

Retail Gross sales (PY) =
CALCULATE((Retail Gross sales)
            ,'Time Intelligence'(Time Measures) = "PY"
            ,USERELATIONSHIP('Bridge_L4L'(L4LKey_PY), 'DIM_L4L'(L4LKey))
            )

Nun sind die Ergebnisse das, was erwartet wird.

Hier der erste Fall:

Abbildung 6 – Die Ergebnisse für die Filiale in Rom für 2024. Jetzt sind die Ergebnisse konsistent (Abbildung vom Autor)

Und hier sind die Ergebnisse für den zweiten Fall:

Abbildung 7 – Die konsistenten Ergebnisse für den Laden für 2025 (Abbildung vom Autor)

Wie Sie sehen, sind die PY-Werte demselben L4L-Standing zugeordnet wie die Ergebnisse des aktuellen Jahres.

Jetzt sieht der Benutzer konsistente Ergebnisse, die viel einfacher zu verstehen sind.

Abschluss

Der zusätzliche Aufruf des USERELATIONSHIP() Die Funktion kann in ein Berechnungselement eingefügt und von allen PY-Kennzahlen verwendet werden.

Dies macht die Verwendung ohne zusätzliche DAX-Logik sehr einfach.

Wie auch immer, diese Herausforderung struggle relativ einfach zu lösen. Aber als ich über eine Monat-zu-Monat-Berechnung mit der L4L-Funktionalität nachdachte, wurde mir klar, dass dies ohne etwas DAX-Code nicht möglich wäre. Möglicherweise werde ich in einem zukünftigen Artikel näher darauf eingehen.

Dieser Fall unterstreicht jedoch die Notwendigkeit, beim Entwerfen und Testen einer Lösung die Perspektive des Benutzers zu nutzen.

Es reicht nicht aus, eine technische Perspektive zu verwenden; Bei der Bewertung der Funktionalität und Ergebnisse der Lösung ist die Perspektive des Benutzers viel wichtiger.

Für mich struggle dies eine sehr interessante Erfahrung und sehr nützlich für meine zukünftige Arbeit.

Ich hoffe, dass Sie meinen Ansatz interessant finden. Seien Sie gespannt auf mein nächstes Stück.

Referenzen

Dies ist mein vorheriger Artikel zu diesem Thema:

Hier ist der SQLBI-Artikel über das Like-for-Like-Muster mit einer DAX-Lösung basierend auf modellunabhängigen UDFs.

Wie in meinen vorherigen Artikeln verwende ich den Contoso-Beispieldatensatz. Sie können den ContosoRetailDW-Datensatz kostenlos von Microsoft herunterladen Hier.

Die Contoso-Daten können wie beschrieben unter der MIT-Lizenz frei verwendet werden in diesem Dokument. Ich habe den Datensatz aktualisiert, um die Daten auf aktuelle Daten zu übertragen, und alle für dieses Beispiel nicht benötigten Tabellen entfernt.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert