RANKX ve Parametreleri

RANKX ve Parametreleri

RANKX ile ilgili örneklere devam ediyorum, filter context ve row context’i açmak adına çok güzel bir fonksiyon olduğunu yazarken daha iyi farkettim. Önceki yazılara da göz atmak isteyebilirsiniz: 1, 2

Aşağıdaki gibi bir veri setimiz var.

rankx

Tutar değeri aynı olan birden fazla müşteri var ve bazı müşterilerde tutar yok. Metriklerimiz şöyle:

İadeler := SUM ('Müşteri İadeleri'[İade Tutarı] )
Büyükten Küçüğe := 
RANKX (ALLSELECTED ('Müşteri İadeleri'); [İadeler] )
Küçükten Büyüğe := 
RANKX ( ALLSELECTED ('Müşteri İadeleri'); [İadeler]; ; ASC )

Hepsini aynı matrise düşürüyorum.

rankx topn 2

ALLSELECTED (‘Müşteri İadeleri’) sonucunda kalan müşteriler tablosu neyse, her iki sıralama metriği de, matristeki her bir müşteri satırı için bu tablonun tüm satırlarını iterate edecek.

“Büyükten Küçüğe” metriğinin neyi gördüğünü bulalım:

Büyükten Küçüğe Neyi Görüyor := 
CONCATENATEX ( ALLSELECTED ('Müşteri İadeleri'); [İadeler] ; "-" )
rankx topn 3

İlk sıradaki “Müşteri I” için filter context ‘te metrik çalışmaya başlamadan önce sadece kendisi var. ALLSELECTED (..) ile seçili tüm müşterileri gördü (filter context’i değişti). Bu tabloda gördüğü her bir satır için [İadeler] ‘i hesapladı, en sonunda bulunduğu satırdaki müşterinin değerine göre (300’e göre) sırasını buldu.

Aynı işlemi ikinci sıradaki Müşteri F için yaptı. Müşteri G için yaptı … Ta ki matristeki tüm müşterileri bitirene kadar.

CONCATENATEX ile matristeki her bir satır için iterate edilen tabloda gördüğü değerlerin listelenebiliyor olması, iterator’ların çalışma mantığını anlamak açısından güzel bir örnek. (Bir diğer güzel örnek de EARLIER fonksiyonu, buna da göz atmak isteyebilirsiniz.)

Metrik çalışmaya başlamadan önce gördüğü filter context’te sadece kendisi var cümlesi için de bu yazıya lütfen.

Toplam satırı için niye 1 gösteriyor: Bu satır için [İadeler] metriğinin değeri 1,200, gördüğü listedeki değerlerden daha yüksek, bu yüzden 1 gösteriyor.

[Küçükten Büyüğe] metriğinin olduğu sütundaki toplam satırında 10 göstermesinin gerekçesi de aynı, elinde 9 tane değer var (boşlar dahil), 1200 hepsinden daha büyük, sıralamayı ters yaptığımız için de bu sefer 10 hesaplıyor.

Matristeki değerlerden kaynaklanan sıra numaralarını düzeltmeye çalışalım:

rankx topn 4

Bazı değerler “boş” olsa da RANKX bunları bir değer olarak dikkate alıyor. Almamasını sağlayabiliriz, yapmamız gereken şeylerden biri RANKX’in iterate ettiği tabloyu, [İadeler] metriği ya da ‘Müşteri İadeleri'[İade Tutarı] sütun değeri “boş olmayacak” şekilde filtrelemek.

Deneyelim:

Küçükten Büyüğe Deneme 1 :=
RANKX (
    FILTER (
        ALLSELECTED ( 'Müşteri İadeleri' );
        'Müşteri İadeleri'[İade Tutarı] > 0
    );
    [İadeler];
    ;
    ASC
)
rankx topn 5

Tam istediğimiz gibi olmadı henüz!

Fakat rakamların değiştiğine dikkatinizi çekerim. FILTER koşulu ile yazdığımız kısım aslında tabloyu iade tutarı olan satırlar şeklinde filtreledi, RANKX’in iterate ettiği tabloda artık bu boş satırlar yok, her iki sıralamanın gördüğü değer listesine bakalım:

Küçükten Büyüğe Neyi Görüyor :=
CONCATENATEX ( ALLSELECTED ('Müşteri İadeleri') ; [İadeler] ; "-" )
Küçükten Büyüğe Deneme 1 Neyi Görüyor =
CONCATENATEX (
    FILTER (
        ALLSELECTED ( 'Müşteri İadeleri' ),
        'Müşteri İadeleri'[İade Tutarı] > 0
    ),
    [İadeler],
    "-"
)
rankx topn 6

RANKX ‘in iterate ettiği tabloda boş değerli satırlar yok ama Müşteri D ve E için bu müşterilerin boş değerlerini gördüğü listeyle karşılaştırmaya devam ediyor!

Eğer [İadeler] metriği boş ise sıralama yapmamasını sağlamalıyız!

Küçükten Büyüğe Deneme 2 =
IF (
    NOT ( ISBLANK ( [İadeler] ) ),
    RANKX (
        FILTER (
            ALLSELECTED ( 'Müşteri İadeleri' ),
            'Müşteri İadeleri'[İade Tutarı] > 0
        ),
        [İadeler],
        ,
        ASC
    )
)
rankx topn 7

1-4-7 diye giden sıralamayı 1-2-3 şeklinde değiştirmek için RANKX’in opsiyonel parametrelerinden SKIP-DENSE ‘i kullanabiliriz.

Küçükten Büyüğe Deneme 3 =
IF (
    NOT ( ISBLANK ( [İadeler] ) ),
    RANKX (
        FILTER (
            ALLSELECTED ( 'Müşteri İadeleri' ),
            'Müşteri İadeleri'[İade Tutarı] > 0
        ),
        [İadeler],
        ,
        ASC,
        DENSE
    )
)
rankx topn 8

Aynı formülü şöyle de yazabiliriz:

Küçükten Büyüğe Deneme 4 =
IF (
    NOT ( ISBLANK ( [İadeler] ) ),
    RANKX (
        FILTER ( ALLSELECTED ( 'Müşteri İadeleri' ), NOT ( ISBLANK ( [İadeler] ) ) ),
        [İadeler],
        ,
        ASC,
        DENSE
    )
)

İade tutarı sütunu sıfır mı değil mi koşulu yerine [İadeler] metriği boş değilse demiş olduk, aynı kapıya çıkacaktır.

rankx topn 9

Son bir düzeltme de toplam satırı için yapalım, bu satır için sıralama yapmak manasız!

Küçükten Büyüğe Deneme 5 :=
IF (
    HASONEVALUE ( 'Müşteri İadeleri'[Müşteri] );
    IF (
        NOT ( ISBLANK ( [İadeler] ) );
        RANKX (
            FILTER ( ALLSELECTED ( 'Müşteri İadeleri' ); NOT ( ISBLANK ( [İadeler] ) ) );
            [İadeler];
            ;
            ASC;
            DENSE
        )
    )
)
rankx topn 10

Eşitlik durumunu bozacak bir parametresi yok RANKX’in. Fakat bunu da ufak bir “hileyle” çözebiliriz, RANKX’in sıraladığı [İadeler] metriğinine çok küçük ve her müşteri için farklı olacak bir değer ekleyebiliriz. Tabloda her müşterinin ID’si farklı, bu sütunu bu amaçla kullanabiliriz.

Küçükten Büyüğe Son :=
IF ( HASONEVALUE('Müşteri İadeleri'[Müşteri]);
     IF(
        NOT( ISBLANK ([İadeler] ));
        RANKX ( FILTER ( ALLSELECTED ('Müşteri İadeleri') ; NOT (ISBLANK ([İadeler]))) ;
        [İadeler] + DIVIDE ( CALCULATE ( SELECTEDVALUE ('Müşteri İadeleri'[Müşteri ID])) ; 10000 ); ; ASC ; DENSE )
     )
)

rankx topn 11

SELECTEDVALUE ‘nun başında niye CALCULATE var için bu yazıdaki olası hatalara göz atabilirsiniz.

Önceki yazılardakine benzer bir kaç şey daha yapalım: TopN seçimi için bir tablomuz var gene. TopN iadeyi bulalım.

TopN_İadeler :=
VAR Secim =
IF ( HASONEFILTER ('TopSeçim'[Değer]) ;
    SELECTEDVALUE('TopSeçim'[Değer]) ;
    MAX ('TopSeçim'[Değer])
)
RETURN
    SWITCH (TRUE();
    [Küçükten Büyüğe Son] <= Secim ; [İadeler]
    )
rankx topn 13

Dip toplamı düzeltelim:

TopN_İadeler Doğru Dip Toplam :=
IF ( HASONEVALUE ('Müşteri İadeleri'[Müşteri]);
    [TopN_İadeler];
    SUMX ( VALUES ('Müşteri İadeleri'[Müşteri]) ; [TopN_İadeler]
    )
)
rankx topn 14

TopN seçimine göre doğrudan toplam iadeyi hesaplamak için aşağıdaki gibi bir metrik de yazabiliriz.

TopN_İadeler_CALCULATE =
CALCULATE (
    [İadeler],
    FILTER ( 'Müşteri İadeleri', [Küçükten Büyüğe Son] <= [TopN Seçim] )
)
rankx topn 16


Yazıdaki modeli indirebilirsiniz.

Sadece üyeler görebilir. Hızlı üyelik için sosyal medya hesabınızla giriş yapabilirsiniz!

Bloga sosyal medya hesabınızla hızlı üye olmak için ilgili ikonu tıklayabilirsiniz.

“RANKX ve Parametreleri” üzerine 4 yorum

  1. Yine çok değerli, heyecanla okuduğum bir makale. Çok ince detaylar var. Emekleriniz ve paylaşımlarınız için minnettarım 🙂
    Buradaki ” [Küçükten Büyüğe Son] ” metriğini, SQL’deki Row_Number() fonksiyonunun işlevini karşılamak amacıyla kullanabilir miyiz veya buna yönelik bir öneriniz var mıdır? Teşekkürler.

Yorum yapın

PowerBI İstanbul

Power BI, Power Query, DAX, Azure servisleri, SSAS, DW, R, veri madenciliği, veri modelleme ve veri görselleştirme üzerine Türkçe bilgi içeriğine katkı sağlamayı amaçlar.

Intellect BI blog sitesidir.

Intellect BI & PowerBI İstanbul, Microsoft Data Analytics ve Power BI Partneri 'dir.

Blog Yazılarına Üye Olun

Blog yazıları, eğitim ve meetup duyuruları posta kutunuza gelsin!

6,5K Üye
Sosyal Medya
İletişim

pbi (at) powerbi.istanbul