1. Şirketin sorusu ve brif
Kim soruyor? Pazarlama müdürü. Önümüzdeki çeyrekte bir “geri kazanma” (win-back) kampanyası yapılacak. Bütçe sınırlı: herkese indirim kodu gönderilmeyecek.
Hangi karar? Kampanya kime gidecek, hangi segment ve şehre öncelik verilecek? Brif üç soruya iniyor:
- Kaç müşteriyi kaybettik ve bu oran hangi grupta yüksek?
- Kaybettiğimiz müşteriler geçmişte ne kadar harcamıştı?
- Henüz kaybetmediğimiz ama kaybetmek üzere olduğumuz müşteriler kim?
Bu vaka, Müşteri analitiği: yeni, geri dönen, kayıp, kohort, RFM dersindeki tekniklere dayanır. Oradaki [Kayıp Müşteri] ölçüsü dönem bazlıdır: “geçen 12 ayda alıp bu dönemde almayan”. Burada kampanya için farklı bir tanım gerekiyor: müşteri bazında, son siparişten bu yana geçen gün sayısı.
2. Veri ve model
| Tablo | Kullanım |
|---|---|
Satislar | Sipariş tarihi, durum (İptal hariç), kanal, tutar. |
Musteriler | Segment, şehir, bölge, yaş grubu. 150 kayıtlı müşteri. |
Tarih | Tarih filtresini kaldırmak ve “tarihe göre” sürüm için. |
Veri sınırları:
- Satış verisi 22.06.2022’de başlar, 31.12.2024’te biter. “Bugün” yerine bu veri sonu tarihini kullanırız.
TODAY()kullansaydık her müşteri birkaç ay sonra “kayıp” görünürdü. - 150 müşteriden 14’ü hiç sipariş vermemiş. Onlar “kayıp” değil, “hiç kazanılmamış” müşteridir; paydaya girmezler.
- 150 müşterinin yalnızca 140 farklı adı var: aynı adı taşıyan müşteriler var. Liste ve gruplamada
Musteriler[MusteriNo]kullan, adı yalnızca etiket olarak göster. - Şehri boş 7 müşteri var. Şehir kırılımında “(Boş)” satırı görünür; gizleme, raporda veri kalitesi notu olarak bırak.
3. Analiz adımları
Adım 1: Kayıp tanımı. Kural: iptal edilmemiş son siparişinden bu yana 180 gün veya daha fazla geçen müşteri kayıptır; 90–179 gün arası “risk altında”dır. Önce yapı taşları:
Son Sipariş =
CALCULATE(
MAX(Satislar[Tarih]),
REMOVEFILTERS(Tarih),
REMOVEFILTERS(Satislar[Kanal]),
Satislar[Durum] <> "İptal"
)
Veri Sonu = MAXX(ALL(Satislar), Satislar[Tarih])
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, [Veri Sonu], DAY))
REMOVEFILTERS(Tarih) önemli: rapor sayfasında bir yıl seçilse bile müşterinin gerçek son siparişini buluruz. REMOVEFILTERS(Satislar[Kanal]) ise kanal kırılımında “bu kanaldaki son sipariş” yerine “herhangi bir kanaldaki son sipariş”i verir. Veri Sonu için ALL(Satislar) üzerinde yineleriz; hiçbir dilimleyici bu tarihi değiştirmez.
Bulgu: Sipariş vermiş 136 müşterinin 89’u aktif (90 günden az), 20’si risk altında (90–179 gün), 27’si kayıp (180+ gün).
Adım 2: Kayıp sayısı ve oranı.
Son Sipariş =
CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), REMOVEFILTERS(Satislar[Kanal]), Satislar[Durum] <> "İptal")
Veri Sonu = MAXX(ALL(Satislar), Satislar[Tarih])
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, [Veri Sonu], DAY))
Kaybedilen Müşteri =
COUNTROWS(
FILTER(
CALCULATETABLE(VALUES(Satislar[MusteriNo]), REMOVEFILTERS(Tarih), Satislar[Durum] <> "İptal"),
[Sessiz Gün] >= 180
)
)
Alışveriş Yapmış Müşteri = CALCULATE([Müşteri Sayısı], REMOVEFILTERS(Tarih))
Kayıp Oranı % = DIVIDE([Kaybedilen Müşteri], [Alışveriş Yapmış Müşteri])
Müşteri listesini Satislar üzerinden alıyoruz (VALUES(Satislar[MusteriNo])). Böylece kanal ve kategori gibi olgu tablosundaki filtreler de listeyi daraltır. FILTER içindeki [Sessiz Gün] çağrısı her müşteri için bağlam geçişi yapar.
Bulgu: 27 / 136 = %19,9 kayıp oranı. Her beş müşteriden biri altı aydır sipariş vermiyor.
Adım 3: Segment, yaş, şehir ve kanal kırılımı. Aynı ölçüyü matriste satırlara koymak yeter.
| Kırılım | Kayıp / alışveriş yapan | Kayıp oranı |
|---|---|---|
| Premium | 8 / 30 | %26,7 |
| Bireysel | 15 / 77 | %19,5 |
| Kurumsal | 4 / 29 | %13,8 |
| Yaş 35-44 | 8 / 29 | %27,6 |
| Yaş 45-54 | 7 / 26 | %26,9 |
| Yaş 18-24 | 4 / 18 | %22,2 |
| Yaş 25-34 | 5 / 34 | %14,7 |
| Yaş 55+ | 3 / 29 | %10,3 |
| Marmara bölgesi | 13 / 36 | %36,1 |
| İç Anadolu bölgesi | 6 / 44 | %13,6 |
| Kanal: Mağaza | 17 / 70 | %24,3 |
| Kanal: Mobil | 23 / 117 | %19,7 |
| Kanal: Web | 22 / 113 | %19,5 |
Şehir düzeyinde İstanbul öne çıkıyor: 27 müşteriden 10’u kayıp (%37,0). Bursa 3/9, Konya 2/5. Ancak Konya’da yalnızca 5 müşteri var; küçük gruplarda oran tek bir müşteriyle %20 oynar. Raporda oranın yanına mutlaka müşteri sayısını yaz.
Adım 4: Kaybedilen müşterilerin geçmiş harcaması.
Son Sipariş =
CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), REMOVEFILTERS(Satislar[Kanal]), Satislar[Durum] <> "İptal")
Sessiz Gün =
VAR Son = [Son Sipariş]
RETURN IF(NOT ISBLANK(Son), DATEDIFF(Son, MAXX(ALL(Satislar), Satislar[Tarih]), DAY))
Kaybedilen Ciro =
CALCULATE(
[Net Satış],
REMOVEFILTERS(Tarih),
FILTER(VALUES(Musteriler[MusteriNo]), [Sessiz Gün] >= 180)
)
Bulgu: Kaybedilen 27 müşteri, tüm dönemde 185.576 ₺ harcamış. Bu, toplam net satışın (1.250.772 ₺) %14,8’i. Kaybedilen müşteri başına geçmiş harcama 6.873 ₺; kalan müşterilerde 9.772 ₺. Yani genelde daha az harcayanları kaybediyoruz. Ama Premium istisna: kaybedilen cironun 82.328 ₺’si (%44) yalnızca 8 Premium müşteriden geliyor. Premium müşteri ortalama 11,1 sipariş veren, 16.271 ₺ harcayan bir müşteri; böyle birinin altı ay sessiz kalması güçlü bir sinyaldir.
Adım 5: Zaman içinde kayıp. Brif “şu an” soruyor, ama yönetim “artıyor mu?” diye de soracak. Veri sonu yerine bağlamdaki son tarihi kullanan bir sürüm:
Son Sipariş (Tarihe Kadar) =
VAR Gun = MAX(Tarih[Tarih])
RETURN CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), Satislar[Tarih] <= Gun, Satislar[Durum] <> "İptal")
Kayıp (Tarihe Göre) =
VAR Gun = MAX(Tarih[Tarih])
VAR Musteriler180 =
FILTER(
CALCULATETABLE(VALUES(Satislar[MusteriNo]), REMOVEFILTERS(Tarih), Satislar[Tarih] <= Gun, Satislar[Durum] <> "İptal"),
DATEDIFF([Son Sipariş (Tarihe Kadar)], Gun, DAY) >= 180
)
RETURN COUNTROWS(Musteriler180)
Bulgu: Çeyrek sonlarında kayıp müşteri sayısı: 2023-Ç4 7, 2024-Ç1 12, Ç2 15, Ç3 20, Ç4 27. Bir yılda dört katına yakın arttı. Müşteri tabanı da büyüyor, ama artış hızı ciddi.
Adım 6: Risk altındaki müşteriler listesi. Kampanyanın asıl hedefi bu liste: henüz kaybedilmemiş, 90–179 gündür sessiz müşteriler.
EVALUATE
VAR Liste =
ADDCOLUMNS(
VALUES(Musteriler[MusteriNo]),
"Müşteri", CALCULATE(MAX(Musteriler[Musteri])),
"Segment", CALCULATE(MAX(Musteriler[Segment])),
"Son", CALCULATE(MAX(Satislar[Tarih]), REMOVEFILTERS(Tarih), Satislar[Durum] <> "İptal"),
"Ciro", CALCULATE([Net Satış], REMOVEFILTERS(Tarih))
)
VAR Riskli =
FILTER(Liste, NOT ISBLANK([Son]) && DATEDIFF([Son], DATE(2024, 12, 31), DAY) >= 90 && DATEDIFF([Son], DATE(2024, 12, 31), DAY) < 180)
RETURN TOPN(10, Riskli, [Ciro], DESC)
ADDCOLUMNS içinde MAX(Musteriler[Segment]) yazarsan satır bağlamı filtreye dönüşmez ve her satıra tüm tablonun en büyük değeri (“Premium”) gelir. Bu vakayı hazırlarken ilk denemede tam olarak bu oldu ve liste “hep Premium” göründü. CALCULATE(MAX(...)) bağlam geçişi yapar.Bulgu: 20 risk altındaki müşteri, geçmişte toplam 122.492 ₺ harcamış. 18’i Bireysel, 2’si Kurumsal; risk listesinde hiç Premium müşteri yok. Premium’daki sorun 180+ gün grubunda: 8 kayıp. İlk üç: 97 no.lu Mehmet Doğan (90 gün, 19.457 ₺), 24 no.lu Gamze Kaya (Kurumsal, 97 gün, 16.354 ₺), 51 no.lu Eren Çelik (109 gün, 11.573 ₺).
4. Rapor sayfası taslağı
| Konum | Görsel | Alanlar |
|---|---|---|
| Üst şerit | 4 kart | Alışveriş yapmış müşteri (136), Kaybedilen (27), Kayıp oranı (%19,9), Kaybedilen ciro (185.576 ₺) |
| Sol orta | Çizgi grafik | X: Tarih[YilCeyrek], Y: Kayıp (Tarihe Göre) |
| Sağ orta | Çubuk grafik (yatay) | Segment ve yaş grubu; değer: Kayıp Oranı %, araç ipucunda müşteri sayısı |
| Sol alt | Doldurulmuş harita veya tablo | Şehir; Kayıp Oranı % ve Alışveriş Yapmış Müşteri yan yana |
| Sağ alt | Tablo | Risk listesi: MusteriNo, ad, segment, son sipariş, sessiz gün, geçmiş ciro; ciroya göre azalan |
| Sayfa notu | Metin kutusu | “Kayıp: veri sonu (31.12.2024) itibarıyla 180+ gün sipariş yok.” |
Risk tablosuna bir dilimleyici (Slicer) olarak “sessiz gün eşiği” eklemek istersen Segmentasyon dersindeki ne olur (what-if) parametresini kullan: 180 sabiti parametre değerine dönüşür.
5. Bulgu özeti ve öneri
- Kayıp oranı %19,9 (27 / 136) ve bir yılda 7’den 27’ye çıktı. Kayıp takibi aylık KPI olmalı.
- Premium en yüksek orana sahip (%26,7) ve kaybedilen cironun %44’ü bu segmentten. Premium için 180 gün yerine daha kısa bir uyarı eşiği (ör. 60 gün) tanımla; bu müşteriler ortalama 11 sipariş veriyor, uzun sessizlik normal değil.
- Marmara ve özellikle İstanbul (%37,0) öne çıkıyor. Bölge ekibiyle teslimat ve rakip etkisini konuş; küçük şehirlerde oranı müşteri sayısıyla birlikte oku.
- Kampanya önce risk listesine gitsin: 20 müşteri, 122.492 ₺ geçmiş ciro. Kaybedilmişlere göre geri kazanmak daha ucuzdur.
- 35-54 yaş grubunda oran %27 civarında, 55+ grubunda %10,3. Mesaj ve kanal seçimini yaş grubuna göre ayır.