Relacja dwukierunkowa czy CROSSFILTER()?
Spis treści:
W Power BI relacje między tabelami pozwalają nam łączyć ze sobą dane oraz filtrować jedne dane na podstawie drugich. Jednakże, w niektórych sytuacjach nie wystarczy jedynie stworzyć relacji pomiędzy tabelami – to, w którą stronę „płynie” nasz filtr, ma ogromny wpływ na to, co wyświetli nam raport. Zdarza się tak, że filtr będzie musiał działać w obu kierunkach między dwiema tabelami. W takich sytuacjach konieczne będzie użycie relacji dwukierunkowej, którą możemy ustawić na dwa sposoby – ręcznie, konfigurując kierunek filtrowania w modelu danych lub korzystając z funkcji CROSSFILTER(), która pozwala nam tymczasowo zmienić kierunek filtrowania w konkretnym obliczeniu. W tym materiale przedstawimy, kiedy warto użyć ręcznego ustawienia tej relacji, a kiedy lepiej skorzystać z funkcji CROSSFILTER().
Przykład 1 – relacja dwukierunkowa
Mamy przykładową bazę danych załadowaną do modelu Power BI:
Relacje pomiędzy tabelami wyglądają następująco:
Na stronie raportu Power BI chcemy rozliczyć liczbę zleceń oraz wartość zleceń każdego klienta.
Tworzymy wizualizację tabeli, w której wykorzystamy z tabeli klienci pole klient, z tabeli zlecenia pole wartość dwukrotnie, jedno pole będzie sumą zleceń, a drugie liczbą zleceń:
Druga wizualizacja na stronie raportu ma przedstawiać liczbę reklamacji dla każdego klienta.
Tworzymy wizualizację tabeli, w której wykorzystamy z tabeli klienci pole klient, z tabeli reklamacje pole ID zlecenia, które następnie zliczymy:
Dane „poukładały” się właściwie, ponieważ w modelu relacji zostały ustawione odpowiednie kierunki przepływu danych:
Tabela wymiaru klienci „ma wpływ” (filtruje) na dane w tabeli faktów zlecenia, a tabela zlecenia „ma wpływ” na tabelę reklamacje:
Trzecia wizualizacja będzie przedstawiać, w ujęciu miesięcznym, liczbę zleceń oraz ich wartość, ale tylko w tych miesiącach, w których wystąpiły reklamacje.
Z tabeli reklamacje wybieramy pole Data reklamacji-miesiąc, a z tabeli zlecenia wybieramy podwójnie pole wartość, jedną wartość zliczamy a drugą sumujemy:
Jak możemy zauważyć, raport nie wyświetla nam danych poprawnie – przedstawia wszystkie 12 miesięcy, a w każdym z nich wyświetla tę samą wartość, która jest liczbą wszystkich zleceń ogólnie. Dzieje się tak, ponieważ relacja jednokierunkowa nie uwzględnia wzajemnego wpływu między tabelami zlecenia i reklamacje. Aby rozwiązać ten problem, zmienimy typ relacji na dwukierunkowy.
Aby to zrobić, przechodzimy do widoku modelu, następnie klikamy prawym przyciskiem myszy na relację, wybieramy Właściwości, a następnie zmieniamy kierunek filtrowania na „Oba”:
Teraz, gdy relacja między tabelami jest poprawnie ustawiona jako dwukierunkowa, filtracja działa prawidłowo i nasze dane są wyświetlane zgodnie z naszymi oczekiwaniami:
Przykład 2 – funkcja CROSSFILTER()
Czasami zdarza się jednak, że nie chcemy, by zmiana stanu relacji miedzy tabelami była trwała. Funkcja CROSSFILTER(), w porównaniu do relacji dwukierunkowej, której ustawienie jest stałe, jedynie tymczasowo zmienia kierunek lub stan relacji między dwoma tabelami. Oznacza to, że zmiana w relacji, którą wykonamy, działać będzie jedynie na czas wykonywania konkretnego zapytania.
Składnia funkcji CROSSFILTER():
CROSSFILTER(
,
,
)
Gdzie:
- < kolumna_z_tabeli1> – kolumna z jednej strony relacji (z pierwszej tabeli)
- < kolumna_z_tabeli2> – kolumna z drugiej strony relacji (z drugiej tabeli)
- <kierunek_filtracji> – kierunek filtrowania, przyjmuje wartości:
- BOTH – filtrowanie w obie strony
- NONE – brak filtru między tabelami
- ONEWAY – filtrowanie jednokierunkowe (od pierwszej podanej kolumny do drugiej)
Na dzień pisania artykułu, w Excel Power Pivot funkcja CROSSFILTER() nie jest dostępna.
Oznacza to, że w Power Pivot nie możemy tymczasowo zmieniać kierunku relacji na poziomie obliczeń (miar), tak jak w Power BI.
Excelowy model danych nie obsługuje relacji dwukierunkowych.
Użyjemy bazy danych z przykładu pierwszego (relacje są w stanie pierwotnym).
W tym przykładzie chcemy stworzyć dwie wizualizację. Pierwsza z nich ma nam pokazać łączną wartość wszystkich zleceń. Druga natomiast, po wybraniu konkretnego opisu reklamacji we fragmentatorze, wyświetli nam, którzy klienci złożyli reklamacje o danym opisie oraz wartość zlecenia, na które ta reklamacja została złożona.
Tworzymy miarę, która obliczy nam sumę wartości zleceń:
Tworzymy pierwszą wizualizację, w której wykorzystamy naszą miarę:
Działa ona poprawnie:
Tworzymy fragmentator w oparciu o pole „Opis” reklamacji:
Następnie tworzymy drugą wizualizację (klienci i wartość zleceń):
Jak widać, po wybraniu konkretnego opisu reklamacji nic się nie dzieje – wizualizacja wyświetla nam dane dla wszystkich klientów, filtr z tabeli reklamacje nie przechodzi do tabeli klienci przez tabelę zlecenia, z powodu relacji jednokierunkowej. Spróbujmy więc ustawić relacje dwukierunkową:
Po zmianie relacji na dwukierunkową, druga wizualizacja działa już poprawnie. Jednak jednocześnie suma wartości wszystkich zleceń w pierwszej wizualizacji przestała działać prawidłowo – sumuje nam dane w niepożądany sposób. Dzieje się tak, ponieważ relacja dwukierunkowa spowodowała, że filtr na reklamacjach, który miał dotyczyć wizualizacji drugiej, wpływa również na wizualizację pierwszą. W takich sytuacjach ustawienie relacji dwukierunkowej na stałe może prowadzić do błędów i utrudniać nam tworzenie raportów. Tu z pomocą przychodzi funkcja CROSSFILTER(), która pozwoli nam na zmianę kierunku filtrowania tylko w jednej z wizualizacji, opartej o miarę, wykorzystującą funkcję CROSSFILTER(). Dzięki temu model relacyjny się nie zmieni, globalny kierunek filtrowania pozostanie także niezmienny, a my unikniemy niepożądanych efektów ubocznych.
Ustawiamy z powrotem relacje jednokierunkową i tworzymy nową miarę:
WartoscZlecenia =
CALCULATE(
SUM(zlecenia[Wartość]),
CROSSFILTER(zlecenia[ID zlecenia], reklamacje[ID zlecenia], BOTH)
)
Wstawiamy ją do wizualizacji:
Jak widać, wybór opisu reklamacji nie wpływa już na sumę wartości zleceń. Dzięki funkcji CROSSFILTER() filtr z tabeli reklamacje przepływa dwukierunkowo do tabeli zlecenia, co umożliwia poprawne filtrowanie klientów, mimo że relacja w modelu jest jednokierunkowa.
Inną funkcją w Power BI jest TREATAS(), która umożliwia przypisanie filtrów z jednej tabeli do innej. Dzięki temu można obejść ograniczenia jednokierunkowych relacji i wprowadzić bardziej elastyczne filtrowanie – bez zmiany kierunku relacji w modelu.
Wybór pomiędzy relacją dwukierunkową a CROSSFILTER()
Wybór między stałym ustawieniem relacji dwukierunkowej a funkcją CROSSFILTER() zależy od konkretnej sytuacji i potrzeb raportu. Oba podejścia mają wady i zalety, dlatego warto wiedzieć, w jakich sytuacjach jedno sprawdzi się lepiej od drugiego.
Relacja dwukierunkowa :
- Gdy dwukierunkowe filtrowanie jest potrzebne we wszystkich wizualizacjach i obliczeniach w modelu.
- Jeśli model jest prosty i nie przewidujemy konfliktów ani błędów wynikających z wielokierunkowego filtrowania.
- Gdy chcemy uprościć model i nie wymagać pisania dodatkowych miar DAX.
Funkcja CROSSFILTER():
- Gdy potrzebujemy dwukierunkowego filtrowania tylko w wybranych miarach lub konkretnych wizualizacjach.
- Gdy stała relacja dwukierunkowa powoduje błędy, niepożądane efekty lub nadmierne filtrowanie w innych częściach raportu.
- Jeśli chcemy zachować globalnie jednokierunkowe relacje dla lepszej kontroli i wydajności modelu.
- Gdy potrzebujemy elastyczności i precyzyjnego sterowania przepływem filtrów.
Podsumowanie
Relacje dwukierunkowe w modelu danych w Power BI ułatwiają pracę z danymi, poprzez odpowiedni przepływ filtrów. Jednakże ich stałe ustawienie może powodować nieoczekiwane rezultaty i problemy w raportach, np. niepożądany „wpływ” jednej wizualizacji na inną.
Funkcja CROSSFILTER() to wygodne i bezpieczne rozwiązanie, które pozwala wymusić dwukierunkowe filtrowanie w konkretnym obliczeniu (mierze), tam, gdzie jest to potrzebne, bez wpływu na cały model danych. Stosując tę funkcję, zachowujemy kontrolę nad modelem danych i zapewniamy stabilność raportów, unikając niepożądanych efektów ubocznych.