Blog JSystems - uwalniamy wiedzę!

Szukaj

Power BI - DAX liczy, ale nie to, czego oczekujesz

RANKX daje 1 w każdym wierszu albo dziwne miejsca w rankingu

W skrócie

  • RANKX daje 1 w każdym wierszu tabeli, gdy w pierwszym argumencie jest VALUES zamiast ALL albo gdy wyrażenie to goła agregacja kolumny, a dziwne miejsca pojawiają się przy fragmentatorach, remisach i sklepach bez sprzedaży.
  • RANKX liczy wyrażenie dla każdego wiersza podanej tabeli w bieżącym kontekście filtra, więc tabela musi zawierać wszystkie porównywane elementy, a wyrażenie musi przejść do kontekstu każdego z nich.
  • Ranking licz po ALL z tą samą kolumną, która jest w wierszach wizualizacji, z miarą w wyrażeniu, z HASONEVALUE dla wiersza Suma i z warunkiem, który pomija elementy bez wartości.

Piętnaście sklepów, od Nordvelli Online ze 141 772 848,59 zł do Białegostoku z 12 259 226,35 zł, i w każdym wierszu ta sama pozycja: 1. Taki wynik daje RANKX w pierwszej wersji rankingu, a gdy ranking już działa, pojawiają się kolejne zagadki: pozycje zaczynają się od 1 po wybraniu regionu, sklepy bez sprzedaży dostają miejsce, a po remisie brakuje numeru. Na modelu Nordvelli rozkładamy każdy z tych wyników na przyczyny i budujemy ranking, który odpowiada na pytanie zarządu.

Jak to wygląda w praktyce

W macierzy z polem DimSklepy[Nazwa] w wierszach, miarą [Łączna sprzedaż] i miarą Ranking sklepu (bez ALL) = RANKX(VALUES(DimSklepy[Nazwa]), [Łączna sprzedaż]) każdy z 15 sklepów Nordvelli ma pozycję 1, od Nordvelli Online ze 141 772 848,59 zł do Białegostoku z 12 259 226,35 zł. Ten sam efekt daje RANKX(ALL(DimSklepy[Nazwa]), SUM(FaktSprzedaz[WartoscNetto])), czyli wyrażenie bez miary. Wiersz Suma w pierwszej wersji też pokazuje 1.

Poprawny ranking potrafi z kolei pokazywać dziwne miejsca. Po wybraniu regionu Centrum we fragmentatorze Nordvella Warszawa Centrum jest pierwsza, choć w całej sieci zajmuje drugie miejsce. W tabeli miast Katowice, Wrocław i pozostałe miasta z jednym sklepem mają 1, a Warszawa i Kraków puste komórki. Przy filtrze na 2 stycznia 2025 i kategorię Komputery tabela pokazuje 15 sklepów, choć sprzedaż miało 8, a siedem pozostałych dostaje wspólne miejsce 9.

Macierz sklepów Nordvelli z miarą Ranking sklepu (bez ALL), w każdym wierszu pozycja 1
Bez ALL funkcja RANKX porównuje sklep sam ze sobą, więc każdy z 15 sklepów jest pierwszy.

Dlaczego tak się dzieje

RANKX iteruje po tabeli z pierwszego argumentu, dla każdego jej wiersza liczy wyrażenie i porównuje wynik z wartością bieżącego wiersza wizualizacji. W wierszu macierzy filtr zostawia jeden sklep, więc VALUES(DimSklepy[Nazwa]) zwraca listę z jedną pozycją i sklep porównuje się sam ze sobą. ALL zdejmuje filtr tylko z podanej kolumny. Filtry na innych kolumnach tej samej tabeli, na przykład Region z fragmentatora albo Miasto z wierszy wizualizacji, zostają, więc sklepy spoza regionu czy miasta mają w środku RANKX pustą sprzedaż. Według dokumentacji Microsoft RANKX traktuje wartość pustą jak zero, dlatego te sklepy lądują na końcu listy. Ten sam mechanizm daje wspólne miejsce sklepom bez sprzedaży.

Wyrażenie musi zmieniać się razem z wierszem tabeli rankingu. Miara, na przykład [Łączna sprzedaż], wykonuje przejście kontekstu, czyli zamienia wiersz iteracji na filtr. Goła SUM(FaktSprzedaz[WartoscNetto]) tego nie robi i dla każdego sklepu z listy liczy tę samą kwotę, więc wszystkie remisują na pozycji 1. W wierszu Suma wartość całej sieci jest większa od wyniku każdego sklepu, a według dokumentacji RANKX dokłada taką wartość tymczasowo do listy, więc też dostaje 1. Różnicę między ALL i ALLSELECTED opisujemy w poście o udziale procentowym z ALL, ALLSELECTED i REMOVEFILTERS.

Co zrobić krok po kroku

  1. W panelu Dane kliknij prawym przyciskiem tabelę FaktSprzedaz, wybierz Nowa miara i wpisz formułę obok. ALL daje RANKX pełną listę sklepów, DESC ustawia 1 przy największej sprzedaży, a HASONEVALUE zostawia wiersz Suma pusty. Na modelu Nordvelli sklep Nordvella Online ma 1, Warszawa Centrum 2, Katowice 3, a Białystok 15.
    Ranking sklepu =
    IF (
        HASONEVALUE ( DimSklepy[Nazwa] ),
        RANKX (
            ALL ( DimSklepy[Nazwa] ),
            [Łączna sprzedaż],
            ,
            DESC,
            DENSE
        )
    )
  2. W wyrażeniu używaj miary. Gdy nie masz gotowej, owiń agregację w CALCULATE: RANKX(ALL(DimSklepy[Nazwa]), CALCULATE(SUM(FaktSprzedaz[WartoscNetto]))) daje te same pozycje od 1 do 15, a ta sama formuła bez CALCULATE daje 1 przy każdym sklepie.
  3. Kolumna w ALL musi być tą kolumną, która jest w wierszach wizualizacji. W tabeli miast miara z kroku 1 zostawia puste komórki przy Warszawie (4 sklepy) i Krakowie (2 sklepy), bo HASONEVALUE po nazwie sklepu zwraca tam fałsz, a przy miastach z jednym sklepem daje 1. Dla miast zrób osobną miarę: Warszawa ma wtedy 1, Kraków 2, Katowice 3.
    Ranking miasta =
    IF (
        HASONEVALUE ( DimSklepy[Miasto] ),
        RANKX ( ALL ( DimSklepy[Miasto] ), [Łączna sprzedaż], , DESC, DENSE )
    )
  4. Zdecyduj, co ma się dziać po wybraniu regionu albo miasta we fragmentatorze. Z ALL(DimSklepy[Nazwa]) dostajesz miejsce w wybranym regionie: dla Centrum Warszawa Centrum ma 1, Mokotów 2, Ursynów 3, Łódź 4. Ten sam wynik, zapisany wprost, daje ALLSELECTED. Gdy zarząd chce widzieć miejsce w całej sieci także po wybraniu regionu, użyj ALL(DimSklepy): te same sklepy mają wtedy 2, 7, 9 i 10. Filtr z innej tabeli, na przykład rok, działa w obu wersjach tak samo, a ranking przelicza się na sprzedaży z wybranego roku.
    Ranking sklepu w sieci =
    IF (
        HASONEVALUE ( DimSklepy[Nazwa] ),
        RANKX ( ALL ( DimSklepy ), [Łączna sprzedaż], , DESC, DENSE )
    )
  5. Wybierz sposób liczenia remisów w ostatnim argumencie. Ranking regionów Nordvelli po liczbie sklepów ma dwa remisy: Południe i Zachód mają po 3 sklepy, Północ i Wschód po 2. Domyślne SKIP daje 1, 2, 2, 4, 4, 6, a DENSE 1, 2, 2, 3, 3, 4. Inna wartość niż SKIP i DENSE kończy się komunikatem „Nieoczekiwana wartość argumentu TIES w funkcji RANKX. Dozwolone wartości to SKIP i DENSE.” (w angielskiej wersji: „Unexpected value for TIES argument in RANKX function. The admisible values are: SKIP, DENSE.”).
  6. Pomiń elementy bez wartości. Dodaj do warunku NOT ISBLANK([Łączna sprzedaż]), a miara zwróci wartość pustą dla sklepu bez sprzedaży i wizualizacja go ukryje. Dla 2 stycznia 2025 i kategorii Komputery tabela pokazuje wtedy 8 sklepów z pozycjami od 1 do 8 zamiast 15 wierszy, w tym siedmiu z pustą sprzedażą na miejscu 9.
    Ranking sklepu ze sprzedażą =
    IF (
        HASONEVALUE ( DimSklepy[Nazwa] ) && NOT ISBLANK ( [Łączna sprzedaż] ),
        RANKX ( ALL ( DimSklepy[Nazwa] ), [Łączna sprzedaż], , DESC, DENSE )
    )

Jak sprawdzić, że problem zniknął

Kliknij nagłówek kolumny rankingu w tabeli, żeby posortować po niej, tak żeby pozycja 1 była na górze. Sprzedaż ma wtedy maleć z wiersza na wiersz, a numery przy DENSE iść bez przeskoków i bez powtórzeń poza prawdziwymi remisami. Na modelu Nordvelli sklepy idą od 1 do 15, a wiersz Suma jest pusty. Sprawdź ranking w trzech kontekstach: bez fragmentatora, z jednym regionem i z jednym dniem, w którym część sklepów nie sprzedawała. Gdy w którymś pojawia się 1 we wszystkich wierszach albo wspólne miejsce dla pustych wierszy, wróć do kroków 1, 2 i 6.

Zapisuj w nazwie miary, w jakim zbiorze liczysz miejsce (w regionie, w sieci), i trzymaj jedną miarę rankingu na jedną kolumnę wierszy. Gdy ranking ma posłużyć do wybrania najlepszych pozycji, prostszy bywa filtr albo miara z TOPN, opisane w poście o Top N produktów. Gdy miara pokazuje tę samą wartość we wszystkich wierszach także poza rankingiem, przyczyny zebraliśmy w poście o mierze z tą samą wartością w każdym wierszu.

Źródła i sposób sprawdzenia

  • Microsoft Learn: RANKX function (DAX) (źródło)
  • Microsoft Learn: ALL function (DAX) (źródło)
  • Microsoft Learn: ALLSELECTED function (DAX) (źródło)
  • Microsoft Learn: HASONEVALUE function (DAX) (źródło)
  • Sprawdzone zapytaniami DAX na modelu Nordvelli: ranking sklepów i miast, fragmentator regionu, remisy SKIP i DENSE, sklepy bez sprzedaży w wybranym dniu.

Zachowanie programu sprawdziliśmy w Power BI Desktop 2.157 (wydanie z sierpnia 2026 r.) z polskim interfejsem, a przykłady na modelu sieci Nordvella z bezpłatnego kursu Power BI. Microsoft wydaje nową wersję Power BI Desktop co miesiąc, więc nazwy przycisków i limity usługi mogą się zmieniać. Aktualne wartości podaje dokumentacja Microsoft Learn.

Wróć do listy: 131 najczęstszych pytań i problemów związanych z Power BI

Najczęściej zadawane pytania

Dlaczego RANKX zwraca 1 dla każdego wiersza?
Pierwsza przyczyna to VALUES albo sama kolumna w pierwszym argumencie zamiast ALL, przez co w wierszu tabeli lista zawiera tylko bieżący element i porównuje się on sam ze sobą. Druga to wyrażenie bez miary albo CALCULATE, na przykład SUM po kolumnie, które dla każdego elementu daje tę samą kwotę. Na modelu Nordvelli obie wersje dają 1 przy wszystkich 15 sklepach.
Jaka jest różnica między SKIP i DENSE w RANKX?
SKIP, wartość domyślna, zostawia lukę po remisie, a DENSE nadaje kolejnemu elementowi następny numer. Ranking regionów Nordvelli po liczbie sklepów z dwoma remisami daje przy SKIP pozycje 1, 2, 2, 4, 4, 6, a przy DENSE 1, 2, 2, 3, 3, 4. Inna wartość tego argumentu kończy się komunikatem o nieoczekiwanej wartości argumentu TIES.
Dlaczego ranking zaczyna się od 1 po wybraniu regionu we fragmentatorze?
ALL z kolumną nazwy sklepu zdejmuje filtr tylko z tej kolumny, a filtr regionu z tej samej tabeli zostaje, więc ranking liczy miejsca w wybranym regionie. Żeby pokazać miejsce w całej sieci, użyj ALL z całą tabelą sklepów. Na modelu Nordvelli Warszawa Centrum jest pierwsza w regionie Centrum i druga w sieci.
Jak ukryć wiersz Suma i sklepy bez sprzedaży w rankingu RANKX?
Owiń RANKX w IF z warunkiem HASONEVALUE na kolumnie wierszy i dodaj warunek NOT ISBLANK na mierze sprzedaży. Miara zwraca wtedy wartość pustą w wierszu Suma i przy sklepach bez sprzedaży, więc wizualizacja je ukrywa. Na modelu Nordvelli dla 2 stycznia 2025 i kategorii Komputery tabela pokazuje 8 sklepów zamiast 15.

Komentarze (0)

Musisz być zalogowany by móc dodać komentarz. Zaloguj się przez Google

Brak komentarzy...