Statik mi, dinamik mi?
| Statik segment (hesaplanmış sütun) | Dinamik segment (ölçü + bağlantısız tablo) | |
|---|---|---|
| Ne zaman hesaplanır? | Yenilemede | Her etkileşimde |
| Filtrelere tepki | Yok (2024 seçince de tüm zamanlara göre) | Var |
| Eksen/dilimleyicide kullanım | Doğrudan | Bağlantısız tablo üzerinden |
| Performans | Hızlı | Müşteri sayısıyla orantılı |
Dinamik segmentasyon kalıbı
- Sınırları tutan bağlantısız tablo:
MusteriDilimleri(Dilim, Min, Max, Sira). Giriş → Veri gir ile ya da DAXDATATABLEile. - Her müşterinin değerini hesaplayan sanal tablo:
ADDCOLUMNS(VALUES(Musteriler[MusteriNo]), "S", [Net Satış]). - Görünen dilimler üzerinde dolaşıp sınırlar içindeki müşterileri say.
Dilimler (DATATABLE) =
DATATABLE(
"Dilim", STRING, "Min", INTEGER, "Max", INTEGER,
{
{"Küçük", 0, 2000},
{"Orta", 2000, 6000},
{"Büyük", 6000, 15000},
{"VIP", 15000, 999999999}
}
)
ABC (Pareto)
Ürünlerin küçük bir kısmı satışın büyük kısmını getirir. ABC sınıflandırması bunu iş kuralına çevirir: kümülatif payı %70'e kadar olanlar A (yakından izlenir, stoğu bitmemeli), %90'a kadar B, kalanı C (gözden geçirilecek uzun kuyruk). Kümülatif toplamın klasik DAX yolu: “satışı benimkinden büyük ya da eşit olanların toplamı”.
Ne olur (what-if) parametresi
Modelleme → Yeni parametre → Sayısal aralık: ad, veri türü, en küçük, en büyük, artış, varsayılan. Power BI iki şey oluşturur:
FiyatSenaryosu = GENERATESERIES(-0.2, 0.2, 0.05) FiyatSenaryosu Değeri = SELECTEDVALUE(FiyatSenaryosu[FiyatDegisimi], 0)
ve sayfaya bir kaydırıcı dilimleyici ekler. Ölçülerinde [FiyatSenaryosu Değeri]'ni kullanarak senaryo hesaplarsın. Parametre tablosunu eksene koyarsan her senaryoyu yan yana görürsün (ör. kâr eğrisi ve optimum fiyat).
Dört segmentleme yolu: hangisi ne zaman?
Satış direktörü üç şey istiyor: müşterileri yıllık harcamaya göre bantlara ayırmak, her bandın satış payını görmek ve “geçen yıla göre kaç müşteri üst banda çıktı?” sorusunu cevaplamak. Önce hangi yolu kullanacağına karar ver.
| Yol | Filtreye tepki | Eksende kullanım | Maliyet | Doğru olduğu yer |
|---|---|---|---|---|
| Hesaplanmış sütun | Yok | Doğrudan | Yenilemede bir kez | Ömür boyu değer, kayıt kanalı gibi sabit özellikler |
| Ölçü + ilişkisiz bant tablosu | Var | Bant tablosu üzerinden | Her hücrede müşteri sayısıyla orantılı | Keşif, “seçili dönemde hangi bant?” |
| Yüzdelik eşik (ölçü) | Var | Bant tablosu ya da kart | Sıralama + yüzdelik hesap | “En iyi %20” gibi göreli tanımlar |
| Anlık görüntü tablosu | Dondurulmuş | Doğrudan | Kaynakta, ayda bir | Kampanya listeleri, geçiş analizi, denetim |
İlişkisiz bant tablosu: mekanizma ve toplam satırı
MusteriDilimleri tablosunun modelde hiçbir ilişkisi yok. Matrisin satırına Dilim konduğunda filtre yalnızca bu küçük tabloyu daraltır; Satislar'a ulaşmaz. Bu yüzden ölçü üç iş yapar: müşterileri ve satışlarını sanal bir tabloda hesaplar, görünen bant satırlarını dolaşır, sınırlar arasındaki müşterileri toplar. Hazır [Dilimdeki Müşteri] ölçüsü bunu SUMX(MusteriDilimleri, …) ile yapar.
Anti-kalıp: SELECTEDVALUE ile sınır okumak
Naif Dilim Müşterisi =
VAR AltSinir = SELECTEDVALUE(MusteriDilimleri[Min])
VAR UstSinir = SELECTEDVALUE(MusteriDilimleri[Max])
RETURN
COUNTROWS(
FILTER(VALUES(Musteriler[MusteriNo]), [Net Satış] > AltSinir && [Net Satış] <= UstSinir)
)
2024 seçiliyken bant satırları doğru görünür: Küçük 24, Orta 53, Büyük 36, VIP 10. Ama toplam satırı boş gelir. Toplamda dört bant birden görünür, SELECTEDVALUE BLANK döner ve hiçbir müşteri koşulu sağlamaz. SUMX(MusteriDilimleri, …) kalıbı ise toplamda dört bandı tek tek dolaşır ve 123 verir. Kural: ilişkisiz tablodan değer okuyorsan, toplam satırında birden çok satır görüneceğini varsay ve satırları dolaş.
Sınırların çakışması
Bantlar “alt sınır hariç, üst sınır dahil” kuralıyla tanımlı: [S] > Min && [S] <= Max. İki tarafı da dahil yazarsan, tam 6.000 ₺ harcayan bir müşteri hem Orta'da hem Büyük'te sayılır. Satırların toplamı toplam satırından büyük çıkar. Bu modelde tam sınırda müşteri olmadığı için hata bugün görünmez; veri büyüdüğünde sessizce ortaya çıkar. Bunu test sayfana bir kontrol olarak ekle: bant satırlarının toplamı, toplam satırına eşit mi?
Bant payı ve toplam
Bant Satış Payı % = DIVIDE([Dilim Satışı], [Net Satış])
Pay ölçüsü ilişkisiz tabloda kolaydır, çünkü [Net Satış] bant filtresinden etkilenmez: payda her satırda dönemin tamamıdır. 2024'te VIP bandı 10 müşteriyle 184.624 ₺ getirir (%24,7). Tüm yıllar birlikte alındığında VIP'te 34 müşteri ve %56,6 pay görünür. Aynı bant tanımı, dönem uzadıkça müşterileri yukarı taşır. Yıllık eşikleri tüm dönemde kullanma; ya dönemi sabitle ya eşikleri dönem uzunluğuna göre ölçekle.
Göreli segment: yüzdelik eşik
“En iyi %20 müşterimiz satışın ne kadarını getiriyor?” Burada eşik sabit değil; seçili döneme ve kategoriye göre yeniden hesaplanır.
Müşteri 80. Yüzdelik Satışı =
PERCENTILEX.INC(
ADDCOLUMNS(
CALCULATETABLE(VALUES(Satislar[MusteriNo]), Satislar[Durum] <> "İptal"),
"S", [Net Satış]
),
[S], 0.8
)
Üst Beşte Bir Payı % =
VAR Esik = [Müşteri 80. Yüzdelik Satışı]
VAR T =
ADDCOLUMNS(
CALCULATETABLE(VALUES(Satislar[MusteriNo]), Satislar[Durum] <> "İptal"),
"S", [Net Satış]
)
RETURN DIVIDE(SUMX(FILTER(T, [S] >= Esik), [S]), [Net Satış])
2024'te eşik 9.305 ₺; bu eşiği geçen müşteriler satışın %48,4'ünü getirir. Elektronik'te eşik 7.420 ₺ ve pay %57,1; Hediye'de eşik 580 ₺ ve pay %35,1. Neden VALUES(Musteriler[MusteriNo]) değil de Satislar'dan alınan liste? Musteriler'de 150 kayıt var. Seçili dönemde alışveriş yapmayanlar BLANK satışla yüzdelik hesabına girerse eşik aşağı kayar. Kenar durum: eşikte birden çok müşteri varsa >= nedeniyle “%20” biraz fazla müşteri kapsayabilir. Kartın altına gerçek müşteri sayısını yaz.
Segment geçişleri: bu yıl ve geçen yıl
Geçiş sorusunun iki biçimi var. Tek sayı (“kaç müşteri üst banda çıktı?”) bir ölçüyle cevaplanır:
Bandı Yükselen Müşteri =
VAR T = ADDCOLUMNS(VALUES(Musteriler[MusteriNo]), "Bu", [Net Satış], "GY", [Satış GY])
RETURN
COUNTROWS(
FILTER(
T,
VAR B1 = MAXX(FILTER(MusteriDilimleri, MusteriDilimleri[Min] < [Bu] && [Bu] <= MusteriDilimleri[Max]), MusteriDilimleri[Sira])
VAR B0 = MAXX(FILTER(MusteriDilimleri, MusteriDilimleri[Min] < [GY] && [GY] <= MusteriDilimleri[Max]), MusteriDilimleri[Sira])
RETURN NOT ISBLANK(B0) && B1 > B0
)
)
2024'te 28 müşteri üst banda çıktı; 25 müşteri alt banda indi ya da hiç alışveriş yapmadı. Tam geçiş matrisi (2023 bandı × 2024 bandı) için iki ilişkisiz bant tablosu gerekir: biri satırlara, biri sütunlara. Modelde tek tablo varsa geçişi önce bir DAX sorgusuyla doğrula:
EVALUATE
VAR T =
ADDCOLUMNS(
VALUES(Musteriler[MusteriNo]),
"S23", CALCULATE([Net Satış], Tarih[Yil] = 2023),
"S24", CALCULATE([Net Satış], Tarih[Yil] = 2024)
)
VAR T2 =
ADDCOLUMNS(
T,
"Onceki", COALESCE(MAXX(FILTER(MusteriDilimleri, MusteriDilimleri[Min] < [S23] && [S23] <= MusteriDilimleri[Max]), MusteriDilimleri[Dilim]), "Yok"),
"Simdi", COALESCE(MAXX(FILTER(MusteriDilimleri, MusteriDilimleri[Min] < [S24] && [S24] <= MusteriDilimleri[Max]), MusteriDilimleri[Dilim]), "Yok")
)
RETURN GROUPBY(T2, [Onceki], [Simdi], "Musteri", COUNTX(CURRENTGROUP(), 1))
ORDER BY [Onceki], [Simdi]
Sorgu ilginç bir tablo verir: 2023'te Büyük bantta olan 24 müşteriden 7'si yerinde kaldı, 4'ü VIP'e çıktı, 8'i Orta'ya indi, 4'ü hiç gelmedi. 2023'te alışveriş yapmayıp 2024'te gelen 59 müşteri var (“Yok” satırı). Bu satırlar “Yükselen” değildir; yeni müşteridir. Ölçüdeki NOT ISBLANK(B0) koşulu tam olarak bunu ayırır.