Power BI’da Tekrar Eden Verilere Sahip İki Tablo Arasında İlişki Nasıl Kurulmalıdır? – 1
Bu makalede Power BI raporlarımızda, ilişkilendirmek istediğimiz her iki tablonun da tekrar eden veriler içermesi durumunda, diğer bir deyişle 2 fact tablo arasında ilişki kurmamız gerektiğinde neler olduğunu ve aslında nasıl olması gerektiğini inceleyeceğiz.
Power BI Veri Modelleme, sık sık üzerinde durduğumuz bir konu. Ancak yeni başlayanlar ilk önce DAX’ı öğrenme telaşına kapılıyor. Her zaman önerim önce Veri Modeli kavramlarına hakimiyeti sağlamanız yönünde. Yeni başlayanların Veri Modelleme hakkında öğrenmesi gerekenleri kabaca saymak gerekirse şunları söyleyebiliriz; Dim Table & Fact Table nedir, şema nedir, Power BI’ın sevdiği şemalar hangileridir, bunları bilmek uygulama üzerinde ne işe yarar, ilişki kardinalitesi, ilişki yönleri nedir, uygulama üzerinde ne anlama gelir, nasıl olmalıdır, modelimizde olması gerektiği gibi değilse, nasıl oldurulur.
Şimdi buradaki senaryoda aşağıdaki gibi bir üretim, bir de satış tablomuz olduğu senaryoyu inceleyelim.
Tablolarımızda üretim adetleri ve satış adetleri ürün ve tarih bazında tutuluyor.
Üretim Tablosu:
Satış Tablosu:
Amacımız, bu iki tablodan yararlanarak, raporda Ürün Adı ve tarih bazında Satış adedi ve Üretim adetlerini görebildiğimiz bir tablo grafiği oluşturmak.
Şimdi adım adım başlayalım.
Bu iki tabloyu Power BI’a çektikten sonra, her iki tabloda ortak olan sütun, Urun ID olduğu için genelde kullanıcılar ilk davranış olarak direkt ikisi arasında ilişki oluşturuyorlar. Fakat her iki tabloda da, Urun ID birden fazla kez olduğu için ilişki Çok’a çok ilişki olmuş oluyor ve bu ilişkinin default yönü Both oluyor.
Biz sürükle bırak yaptığımızda eğer ilişki türü dikkat edilmesi gereken bir durum içeriyorsa bu pencere otomatik olarak açılıyor, şuanda tablolarımızda many to many ilişki algıladığı için açıldı ve uyarı bölümüne bakacak olursak, bu ilişki türünün raporda anlamlandıramayacağımız şeylere sebep olabileceğine vurgu yapıyor.
Both ilişki yönü, her iki tablonun da birbirini filtreleyebildiği anlamına geliyor. Bu da daha fazla tablo ile çalıştığımız modellerde filtrelerin, tablolar arasındaki ilişki yönü müsade ettiği sürece akıştaki diğer tabloları da filtrelemesi anlamına geliyor. Bu hem döngüsel hatalara sebebiyet verebiliyor hem de performans sorunlarına sebep oluyor. Bu nedenle modellerimizde pek görmek istemediğimiz bir ilişki türü.
Ayrıca bu şekilde iki fact tabloyu direkt birbirine bağlamak, dikkatli bakıldığında report view’da da bazı sıkıntılara yol açıyor.
Şimdi ilk önce bu şekilde, nasıl rapor oluştururuz bir bakalım.
Durumu tek ekrandan rahatlıkla görebilmek için önce tabloların sadece kendi sütunlarından oluşan ayrı ayrı matrixleri oluşturdum. Tabi, genelde böyle değil de her iki tablonun verilerinin bir tabloda yazmasıdır beklentimiz. Onun için de alttaki TEST Tablosunu oluşturdum. Basit kullanıcı hataları görebilmeniz için Test tablosunun Urun Adı sütununu Satışlar tablosundan aldım. Çünkü burada hangi tablodan almam gerektiğine dair bir ayraç yok henüz. Şimdi neler olduğunu inceleyelim.
Sağdaki üretim tablosuna bakın, 50 adet TV üretimi olmasına rağmen, Test Tablosunda görünmüyor. Neden?
Şunu hatırlayın, tabloda ilgili satırdaki filter context ne ise, getirdiğimiz değer hesaplanırken, o içerik üzerinde hesaplanıyor. Yani örneğin yukarıdaki Test Tablosunda, 1.satır için bilgisayar filtreli tabloları görüyor ve böylece bilgisayar adetlerini topluyor.
Test tablosuna Urun Adı sütununu Satışlar tablosundan aldığım için, satılmış olan ürünler olan Bilgisayar, Cep Telefonu ve Kamera’yı getirdi. Ancak hiç TV satışı olmadığı için, TV’yi getiremedi. Dolayısı ile TV için bir hesaplama da olmadı. O halde anlıyoruz ki, raporda oluşturduğumuz görsellerimizin ana verileri – filtreleyicileri tüm verileri içeren ortak bir tablodan gelmeli ki her iki tablodaki veriler de hesaplansın.
Diğer konu; madem TV yok, toplama neden TV’nin değerini de getiriyor diye düşünmüş olabilirsiniz. Aslında burada bilmemiz gereken ayrı bir konu. Kabaca şöyle diyebiliriz; Total satırı, üzerinde gördüğünüz değerlerin toplamı değildir. Orası da filter context mantığı ile çalışır. Ancak orada bir filter context yok, o nedenle de arkada filtresiz olarak gördüğü tüm tablonun değerini getirir.
Özetle; Rapor görsellerimize filtreleyici olarak aldığımız verinin hangi tablodan geldiği çok önemli. Bu verileri, tüm verilerin olduğu ve her iki tabloyu da filtreleyebilen bir tablodan almazsak, bu şekilde birinde olan diğerinde olmayan veriler gözden kaçabilir. Tam tersi düşünelim, Bu sefer, görsele Üretim tablosundan Ürün Adını koymuş olsaydık,, gösterilecek tüm ürünler, üretilmiş olan ürünler olurdu. Bu iyi gibi, ama bu seferde bir tarih seçtiğinizde belki de o tarihte satılmış ama yeni üretim yapılmamış bir ürün var ise, bu kayıtları gözden kaçırmış olacaktık.
Çözüm;
Bu durumda, her iki tablodaki tüm ürünlerin yer aldığı bir ara tablo gereklidir demiştik. Buna “Shared Dimension” deniyor. Eğer veritabanımızda, böyle bir tablo varsa direkt onu Power BI’a alabiliriz. Yoksa aşağıdaki gibi Power Query katmanında 1-2 dakika içerisinde o tabloyu hazırlayabiliriz. Bunun için bir çok yolumuz var, TB’lık bir proje yapmıyorsanız aşağıdaki yöntem ile ilerlenebilir .
1. Home Sekmesinden Transform Data butonu ile PowerQuery’ye geçeriz.
2. Satış ve Üretim Tabloları üzerinde sağ click ile duplicate olmalarını sağlarız.
3.Yeni oluşan bu tablolardan Adet ve Tarih sütunlarını seçip sağ click, Remove Columns ile bu sütunları kaldırırız.
4. Bu tablolardan biri seçili iken Append Queris’e basıp diğer tabloyu seçeriz. Böylece iki tablo alt alta birleşmiş olur. Her iki tablodaki sütun başlığının aynı olduğundan emin olalım. Eğer farklıysa, sütun başlığına çift tıklayıp aynı isimleri verebiliriz.
5. Birleşmiş hallerinde, yinelenen değerler olacağı için iki sütunu da seçip Remove Duplicates seçeneğine tıklayıp tekrar edenleri kaldırırız.
Artık her iki tablodaki UrunID ve UrunAdlarını içeren ve yinelenmeyen harika bir tablomuz var.
Data refresh olduğunda bu iki tablo ayrı ayrı yeniden oluşacak, bir araya gelecek ve yinelenenler kaldırılmış olacak, böylece her iki tabloya eklenen yeni ID’ler ve Ürün Adları bu tabloya da eklenmiş olacak. Yani tablomuz hep güncel olacak. Böyle bir tablonun oluşması için PowerQuery’nin her data refresh’te aynı işlemleri adım adım tekrarlayacağını unutmayalım. Dolayısı ile bu ara tablonun aslında database’den hazır gelmesi büyük modellerin daha performanslı çalışmasını sağlayacaktır. Artık, Üretim(2) tablosunda Urun ID ve ADı var, tablonun adına çift tıklayıp Urunler olarak değiştirelim.
Şimdi PowerQuery penceresini kapatalım ve model bölümüne geçelim. Burada kullanacağım ek tablo Ürünler, ama Satış 2 de modele yüklendi. Onu model içinde bireysel olarak kullanmayağız. onun verileri Ürünler tablosunun içine eklendi bir üstteki işlemde zaten. o halde modele yüklenmesine gerek yok.
Power Query’e geri dönüp modele yüklenmesini Sağlayan “Enable Load” tick işaretini kaldıralım. ardından Power Query’i kapatıp modele geçelim.
Şimdi ilk başta oluşturduğumuz ilişkinin üzerine sağ click yapıp o ilişkiyi silelim.
Esas olması gerekeni yapalım, tüm verilerimizden bir kere içeren Urunler tablosunu sırasıyla Satış ve Üretim tablosuna bağlayalım.
Böylece Power BI’da en performanslı çalışan ve görünmeyen hataları ortadan kaldıran One To Many ilişkisine ulaşmış olduk.
Rapor görünümüne geçip neler olduğuna bir bakalım. Test Tablomuzda Üretim Adetleri Urun Adına göre filtrelenmiyor halen, toplamı gösteriyor. Çünkü, Urun Adı sütununu Satışlar tablosundan getirmiştik o görsele. Modele bakalım sağ taraftan, Satışlar tablosu direkt olarak Üretim tablosunu filtreleyemeyeceği için, o şekilde tablonun toplam değeri gözüküyor. Peki aslında hangi tablo her iki tabloyu da doğru şekilde filtreleyebilir? Artık cevabı biliyoruz. Urunler Tablosu!
Görsele, Urunler tablosundaki Urun Adını getirip, satışlar tablosundan gelen ürün adı’nı kaldıralım. İşte şimdi Ürün bazında her iki tablodaki adetleri de doğru şekilde görebiliyoruz!
Not: Fact tablolarınızda Ürün Adlarının bulunması gereksiz gördüğünüz üzere. Neredeyse hiç bir zaman filtreleyici olarak Fact tablosundan sütun kullanmıyoruz. Her zaman Dimension tabloları kullanmalıyız. Hem son kullanıcınızın kafasını karıştırmamak için hem de Fact tablolarından metinsel verileri kaldırarak Modeli hafifletmek için, PowerQuery katmanındayken, Fact tablolardan ürün isimlerini kaldırmanızı ve yalnızca Dimension tablonuzda tutmanızı tavsiye ederim.
Yazının en başında bahsedilen ürün adına göre Ürün Adedi ve Satış Adetlerini tek bir dilimleyiciden tek tabloda göstermeyi başardık. Bu oluşturduğumuz model temeli, aynı iki tablo arasında tarihe göre de ilişki kurarak, ürünleri tarih bazında göstermemiz için de olanak sağlayacak. Nasıl yapılacağını görmek için bir sonraki yazıyı okumaya devam edebilirsiniz.