Power BI’ın 2022 Aralık ayında tanıttığı INDEX, OFFSET ve WINDOW fonksiyonları, DAX dünyasında büyük bir yenilik sunuyor. Bu fonksiyonlar, daha önce karmaşık ve uzun ifadelerle yapılan işlemleri kolaylaştırarak, kullanıcıların daha hızlı ve sezgisel analizler yapmasına olanak tanıyor. Gelin, bu fonksiyonların detaylarına birlikte bakalım.

INDEX Fonksiyonu

INDEX fonksiyonu, bir görsel tablodaki verileri belirli bir sıralama kriterine göre düzenler ve istenen pozisyondaki değeri döndürür. Daha önce bu işlem için TOPN, MAXX gibi birden fazla fonksiyonun birleşimini kullanmak gerekiyordu. Bu, kodun karmaşıklığını arttırıyor ve performans sorunları yaratabiliyordu. INDEX fonksiyonuyla bu süreç çok daha basit ve hızlı bir hale geldi.

Avantajları

INDEX fonksiyonu, kod yazımını kolaylaştırır ve karmaşık DAX ifadelerine gerek kalmadan istenen sonuçlara ulaşmanızı sağlar.  Performans açısından oldukça etkilidir. Dahili bir DAX fonksiyonu olduğu için büyük veri setlerinde bile hızlı ve sorunsuz çalışır, ekstra hesaplama yükünü azaltır.  Ayrıca, sıralama ve gruplama kriterlerini kolayca özelleştirebilirsiniz. Belirli sütunlara veya veri gruplarına göre pozisyon belirlemek, INDEX ile oldukça pratiktir. 

Örnek: Belirli Bir Satırı Getirme

Bir satış tablosunda görseldeki sıralamaya göre sondan üçüncü satırdaki değeri getirmek istiyoruz.

DAX Formülü:

 INDEX = CALCULATE([Toplam Satislar], 
        INDEX
        (-3, -- Sondan üçüncü değeri alır
        ALL('Sales'[RegionCode],'Sales'[RegionName])
        )
 )

Bu ölçüyü tabloya eklediğinizde, sadece sondan üçüncü sıradaki ülkenin (örneğin Almanya) toplam satışları gösterilir.

Önceki Yöntemle Karşılaştırma

Aynı işlemi TOPN ile yapmak için daha uzun bir kod yazmak gerekiyor:

 TOPN = MAXX(
    TOPN(1,
        TOPN(
            3,
            ALL('Sales'[RegionCode], 'Sales'[RegionName]),
            'Sales'[RegionCode], DESC,
            'Sales'[RegionName], ASC),
        'Sales'[RegionCode], ASC,
        'Sales'[RegionName], DESC),
    [Toplam Satislar]
 )

INDEX fonksiyonu ile bu işlem daha kısa ve anlaşılır hale geliyor.

INDEX Fonksiyonu ile Sıralama Özelleştirme

INDEX fonksiyonunun ORDERBY ve PARTITIONBY parametreleriyle sıralama düzeni özelleştirilebilir ve gruplara göre işlem yapılabilir.

ORDERBY Örneği:

ORDERBY parametresi, tablonuzun hangi sütuna göre sıralanacağını belirler. Aşağıdaki örnekte, Region Name sütununa göre sıralama yaptık ve sıralamayı artan düzende (ASC) olarak belirttik. Daha sonra, bu sıralamaya göre 6. sıradaki Toplam Satışlar değerini getirdik. Böylece, sıralama sonucunda "Northeast" için toplam satış değeri tablodaki 6. sıradan alınmıştır. 

 INDEX_ORDERBY = CALCULATE([Toplam Satislar],
        INDEX(6, ALL('Sales'[RegionCode],'Sales'[RegionName]), 
 ORDERBY('Sales'[RegionName], ASC  
        ))
 )

PARTITIONBY Örneği:

PARTITIONBY parametresi, belirli gruplara bölerek her grup için ayrı bir hesaplama yapmanıza olanak tanır. Örneğin, bir ürün kategorisi içerisinde en yüksek ikinci satırı bulmak istiyorsanız, bu parametre yardımcı olur.

INDEX_PARTITIONBY = 
CALCULATE(
    [Sales Amount], 
    INDEX(
        2, -- Her bir bölmede ikinci sıradaki değeri seç
        ALL('Product'[Category], 'Product'[Brand]), 
        ORDERBY('Product'[Brand],ASC),
        PARTITIONBY('Product'[Category]) -- Sıralamayı her bir kategori için ayrı ayrı uygula
    )
)

OFFSET Fonksiyonu

OFFSET fonksiyonu, tabloda belirttiğiniz pozisyondaki satıra kolayca erişmenizi sağlar. Özellikle önceki veya sonraki satırlarla karşılaştırma yapmanız gerektiğinde büyük bir kolaylık sunar.

Avantajları

OFFSET, karmaşık formüller yazmadan satır bazlı verilere hızlı ve kolay erişim sağlar. Performansı yüksektir ve dahili bir fonksiyon olarak daha az hata riski taşır. Ayrıca, ORDERBY ve PARTITIONBY ile sıralama ve gruplama kriterlerini kolayca özelleştirebilirsiniz.

DAX Formülü:

 OFFSET = CALCULATE(
      [Toplam Satislar], 
      OFFSET(-1, ALL(Sales[RegionCode], Sales[RegionName]))
 )

Bu ölçü tabloya eklendiğinde, bir önceki satırın değeri gösterilecektir.

OFFSET Olmadan Aynı İşlem

OFFSET fonksiyonu olmadan bir önceki satırın toplam satış değerini bulmak daha karmaşıktır. Bu işlem için şu şekilde bir formül yazabilirsiniz:

 Previous_Row_Filter = CALCULATE(
    [Toplam Satislar],
    TOPN(
        1,
        FILTER(
            ALL('Sales'[RegionCode], 'Sales'[RegionName]),
            'Sales'[RegionCode] < MAX('Sales'[RegionCode]) ||
            (
                'Sales'[RegionCode] = MAX('Sales'[RegionCode]) &&
                'Sales'[RegionName] < MAX('Sales'[RegionName])
            )
        ),
        'Sales'[RegionCode], DESC,
        'Sales'[RegionName], DESC
    )
 )

OFFSET'in ORDERBY ve PARTITIONBY Parametreleri

OFFSET fonksiyonunu kullanarak bir önceki satırın satış değerini, belirli bir sıralama kriterine (ORDERBY) ve PARTITIONBY parametresine göre özelleştirerek hesaplayabilirsiniz.

ORDERBY Örneği:

RegionName'e göre sıralanmış bir tabloda, bir önceki satırın değerini bulmak için:

 OFFSET_ORDERBY = CALCULATE(
         [Toplam Satislar], 
         OFFSET(-1, ALL(Sales[RegionCode], Sales[RegionName]), 
         ORDERBY(Sales[RegionName], ASC))
 )

PARTITIONBY Örneği:

Her kategori için bir önceki değeri hesaplamak için PARTITIONBY kullanabilirsiniz:

 OFFSET_PARTITIONBY = CALCULATE(
              [Sales Amount], 
              OFFSET(-1, ALL('Product'[Category],'Product'[Brand]), 
              ORDERBY('Product'[Brand], ASC), 
              PARTITIONBY('Product'[Category]))
 )

WINDOW Fonksiyonu

WINDOW fonksiyonu, birden fazla satır üzerinde hesaplama yapmanızı sağlar. Başlangıç ve bitiş pozisyonu belirleyerek toplama, ortalama gibi işlemleri kolayca gerçekleştirebilirsiniz.

Avantajları

WINDOW, belirli bir aralık veya kategori bazlı hesaplamaları hızlı ve pratik bir şekilde yapmanızı sağlar. Karmaşık formüllere gerek kalmadan, önceki yöntemlerle zor olan işlemleri basitleştirir. Dahili bir fonksiyon olduğu için performansı yüksektir ve büyük veri setlerinde bile hızlı çalışır.

Örnek: Satır Aralığı Toplamı

Aşağıdaki tabloda, mevcut satırın yanı sıra önceki iki satırı kapsayan toplam satış değerini hesaplamak istiyoruz.

DAX Formülü:

 WINDOW = CALCULATE(
[Toplam Satislar],
    WINDOW(-2, -- Başlangıç konumu : Mevcut satırdan onceki ilk iki satiri temsil eder.
                   0, -- Bitiş konumu: Mevcut satırı temsil eder.
            ALL(Sales[RegionCode],Sales[RegionName]),--Gorunen tablodaki sutunlari yaziyoruz. 
            ORDERBY(Sales[RegionName],ASC)  -- Bölge adına göre artan sıralama
 ))

Bu ölçüyü tabloya eklediğinizde, her satır için mevcut ve önceki iki satırın toplamı gösterilir.

WINDOW Fonksiyonu ile İlk İki Satırın Toplamı

Pozisyonları mutlak olarak belirterek sadece sıralamadaki belli satırların toplamını göstermek mümkündür. Aşağıdaki örnekte, tablodaki ilk iki satırın toplamını hesapladık:

 WINDOW_top2 = CALCULATE(
    [Toplam Satislar],
    WINDOW(
        1, ABS, -- İlk satır (Pozisyon türü: Mutlak)
        2, ABS, -- İkinci satır (Pozisyon türü: Mutlak)
        ALL(Sales[RegionCode], Sales[RegionName]), 
        ORDERBY(Sales[RegionName], ASC) 
    )
 )

Bu formülle, tabloda sadece belirtilen pozisyondaki satırların toplamı alınır.

WINDOW Fonksiyonu ile Genel Toplam Hesaplama

Genel toplam satış değerini her satırda göstermek istiyoruz. Bunun için WINDOW fonksiyonu kullanılarak başlangıç ve bitiş pozisyonlarını 1 ve -1 olarak belirtiyoruz.

 WINDOW_GeneralTotal = CALCULATE(
              [Toplam Satislar], 
              WINDOW(
                    1,ABS, 
                    -1,ABS,
                    ALL(Sales[RegionCode], Sales[RegionName]), 
                    ORDERBY(Sales[RegionName], ASC) 
              )
  )

Bu formül, tabloda görünen tüm satırların toplamını her satırda aynı şekilde gösterecektir.

WINDOW Fonksiyonu ile Kümülatif Toplam Hesaplama

Bir satış tablosunda her satır için kümülatif toplamı hesaplamak istiyoruz. Bunun için başlangıç pozisyonu mutlak olarak belirlenirken, bitiş pozisyonu mevcut satıra göre relatif olarak ayarlanır.

 CumulativeTotal = CALCULATE(
    [Toplam Satislar],
    WINDOW(
        1,ABS,    -- Başlangıç pozisyonu: İlk satır (mutlak)
        0, REL,   -- Bitiş pozisyonu: Mevcut satır (relatif)
        ALL(Sales[RegionCode], Sales[RegionName]), 
        ORDERBY(Sales[RegionName], ASC) 
    )
 )

Bu formülle, kümülatif toplam her satırda dinamik olarak hesaplanacaktır.

WINDOW Fonksiyonu ile Kategoriye Göre Ortalama Hesaplama

Bir tablo içerisinde her bir ürünün (brand) kendi kategorisindeki ortalama satış miktarını hesaplamak istiyoruz. Bu hesaplama için WINDOW fonksiyonunu ve PARTITION BY özelliğini kullanıyoruz.

  CategoryAverage = CALCULATE(
    AVERAGEX(
        WINDOW(
            1,ABS, -- İlk satırdan başla
            -1, -- Son satıra kadar
            ABS, -- Mutlak pozisyon
            ALL('Product'[Category], 'Product'[Brand]), 
            ORDERBY('Product'[Category], ASC), 
            PARTITIONBY('Product'[Category]) 
        ),
        [Sales Amount] -- Ortalama alınacak değer
    )
  )

Bu formül, her kategorideki ürünlerin ortalama satış değerini hesaplamak için kullanılır.

Özet ve Sonuç

INDEX, OFFSET ve WINDOW fonksiyonları, DAX dili için çok yönlü ve kullanışlı aracılardır. Bu fonksiyonlar sayesinde daha hızlı, performanslı ve sezgisel çözümler üretebilirsiniz. Bu yeni fonksiyonları projelerinizde aktif olarak kullanarak daha temiz ve etkili bir DAX yazımı deneyimleyebilirsiniz.