Sorun
Satislar tablosunda iki tarih var: Tarih (sipariş) ve TeslimTarihi. İkisi de Tarih tablosuna bağlanmak ister. Ama iki tablo arasında aynı anda yalnızca bir etkin ilişki olabilir. Diğeri pasif (model diyagramında kesik çizgi) kalır.
Bu modelde Satislar[Tarih] → Tarih[Tarih] etkin, Satislar[TeslimTarihi] → Tarih[Tarih] pasif. Tarih tablosu iki “rol” oynar: sipariş takvimi ve teslim takvimi.
Çözüm 1: USERELATIONSHIP
Teslime Göre Satış =
CALCULATE(
[Net Satış],
USERELATIONSHIP(Satislar[TeslimTarihi], Tarih[Tarih])
)
USERELATIONSHIP yalnızca CALCULATE içinde çalışır ve o hesap süresince pasif ilişkiyi etkinleştirir; aynı tablolar arasındaki etkin ilişki geçici olarak devre dışı kalır. Aralık 2023'te verilip Ocak 2024'te teslim edilen sipariş, sipariş ölçüsünde Aralık'a, teslim ölçüsünde Ocak'a yazılır.
Çözüm 2: Boyutu çoğaltmak
İkinci bir tarih tablosu (TeslimTarihi tablosu) oluşturup etkin ilişkiyle bağlamak. Avantajı: kullanıcı aynı görselde iki tarihi ayrı eksenlere koyabilir (ör. sipariş ayı × teslim ayı matrisi). Dezavantajı: model büyür, iki takvim bakım ister, zaman zekâsı ölçüleri hangi takvimi kullandığını bilmelidir.
| Durum | Önerilen |
|---|---|
| Birkaç ölçü ikinci tarihe göre hesaplanacak | USERELATIONSHIP |
| Kullanıcı iki tarihi aynı anda dilimleyecek / eksene koyacak | İkinci tarih tablosu |
| Çok sayıda rol (sipariş, kargo, teslim, fatura) | Genellikle ölçüler + USERELATIONSHIP; gerekirse hesaplama grubu |
CROSSFILTER
Aynı aileden: CROSSFILTER(Sütun1, Sütun2, BOTH | NONE | ONEWAY) bir ilişkinin filtre yönünü hesap süresince değiştirir. Modelde ilişkiyi kalıcı olarak çift yönlü yapmak yerine yalnızca gereken ölçüde kullanılır:
Satılan Ürün Sayısı =
CALCULATE(
COUNTROWS(Urunler),
CROSSFILTER(Satislar[UrunNo], Urunler[UrunNo], BOTH)
)
Kanal dilimleyicisinde “Mağaza” seçiliyse bu ölçü mağazada satılmış ürün sayısını verir; çünkü filtre bu ölçüde Satislar'dan Urunler'e de akar.
Hangi soru hangi tarihi ister?
Teknik çözüm (USERELATIONSHIP ya da ikinci tablo) ikinci adımdır. İlk adım, her sorunun hangi tarih rolüne ait olduğunu belirlemektir:
| İş sorusu | Soran | Tarih rolü |
|---|---|---|
| “Bu ay ne kadar sipariş aldık?” | Satış ekibi | Sipariş tarihi |
| “Bu ay ne kadar gelir tanıyabiliriz?” | Finans | Teslim tarihi |
| “Gelecek hafta kaç teslimat yapacağız?” | Lojistik | Teslim tarihi |
| “Siparişler ortalama kaç günde teslim ediliyor?” | Operasyon | İkisi birlikte (fark) |
Ocak 2024 için sipariş tarihine göre net satış 47.433 ₺, teslim tarihine göre 47.297 ₺. Yıl düzeyinde fark büyür: 2024’te sipariş bazlı 747.066 ₺, teslim bazlı 738.304 ₺. Sınır ayları (Aralık’ta verilip Ocak’ta teslim edilen siparişler) iki ölçüyü birbirinden ayırır.
Teslim tarihi boş olan satırlar
Teslim bazlı ölçünün genel toplamı yine 1.250.772 ₺’dir, ama yıl satırlarının toplamı 1.239.709 ₺ tutar. Aradaki 11.063 ₺, henüz teslim edilmemiş (Durum = “Kargoda”) ve TeslimTarihi boş olan satırlardır. Toplam satırında tarih filtresi olmadığı için bu satırlar sayılır. Power BI yıl ekseninde bunları (Boş) etiketli ayrı bir satırda gösterir. Finans raporunda bu satırı gizlemek yerine “Teslim bekleyen” diye adlandırmak daha dürüsttür.
Anti-kalıp: olgu sütununu tarih dilimleyicisiyle süzmek
USERELATIONSHIP’i bilmeyen biri teslim bazlı ölçüyü şöyle kurar:
Teslim Satışı (hatalı) = VAR Bas = MIN(Tarih[Tarih]) VAR Son = MAX(Tarih[Tarih]) RETURN CALCULATE([Net Satış], Satislar[TeslimTarihi] >= Bas, Satislar[TeslimTarihi] <= Son)
Ocak 2024 satırında sonuç 44.996 ₺; doğrusu 47.297 ₺. Eksik 2.301 ₺, Aralık 2023’te verilip Ocak’ta teslim edilen siparişlerdir. Sebep: etkin ilişki hâlâ çalışıyor. Ocak filtresi önce sipariş tarihine göre süzüyor, ölçünün koşulu bunun üstüne ekleniyor. Sonuç “Ocak’ta verilip Ocak’ta teslim edilenler” oluyor. İki düzeltme var:
Teslim Satışı (filtre kaldırarak) = VAR Bas = MIN(Tarih[Tarih]) VAR Son = MAX(Tarih[Tarih]) RETURN CALCULATE([Net Satış], REMOVEFILTERS(Tarih), Satislar[TeslimTarihi] >= Bas, Satislar[TeslimTarihi] <= Son) Teslim Satışı (ilişkiyle) = CALCULATE([Net Satış], USERELATIONSHIP(Satislar[TeslimTarihi], Tarih[Tarih]))
İkisi de 47.297 ₺ verir. İkincisi tercih edilir: niyeti açıkça söyler ve zaman zekâsı fonksiyonlarıyla birlikte çalışır. İlk kalıp, hazır [Yoldaki Sipariş] ölçüsündeki gibi iki tarih sütununu aynı anda karşılaştırman gerektiğinde gerekir (“sipariş verilmiş ama teslim edilmemiş”).
USERELATIONSHIP ve zaman zekâsı birlikte
Finans teslim bazlı YTD istiyor. Yeni bir YTD formülü yazmana gerek yok. Var olan ölçüyü pasif ilişkiyle sarmalarsın:
Teslime Göre YTD = CALCULATE([Satış YTD], USERELATIONSHIP(Satislar[TeslimTarihi], Tarih[Tarih]))
Dıştaki CALCULATE’in etkinleştirdiği ilişki, içteki ölçünün bütün hesabı boyunca geçerlidir. Mayıs 2024’te teslim bazlı YTD 235.031 ₺, sipariş bazlı YTD 235.863 ₺. Aynı yöntem adet, sipariş sayısı ya da kargo süresi için de çalışır. Ocak 2024’te teslim edilen siparişlerin ortalama kargo süresi 2,74 gün, Ocak’ta verilen siparişlerinki 2,67 gün.
İkinci tarih tablosuna ne zaman geçmeli?
Lojistik müdürü bir matris istiyor: satırlarda sipariş ayı, sütunlarda teslim ayı, hücrede sipariş sayısı. Bu soru USERELATIONSHIP ile cevaplanamaz, çünkü aynı görselde aynı tablonun iki rolü aynı anda filtre olamaz. Burada ikinci bir tarih tablosu (ör. TeslimTakvimi) gerekir. Bu modelde siparişlerin %91,7’si verildiği ay içinde teslim ediliyor. Matrisin köşegeni dolu, köşegen dışı ise sınır aylarındaki kaymayı gösterir.