Yakın zamanda bir SSAS tablo modeli oluşturduk, böylece kullanıcılarımız PowerView üzerinden erişebilirler. TotalActiveItems
Bir formülü kullanmak için olgu tablolarımızdan birine ilişkin bir önlemimiz var :
TotalActive:=COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)
Bu gerektiği gibi harika çalışıyor ama şimdi her ay için ilk 10 ebeveyni alma isteğimiz var TotalActive
.
Referans için, işte bizim modelimizin bir parçasıdır:
create table factStats
(
StatsID INT IDENTITY NOT NULL PRIMARY KEY,
DevID INT NOT NULL,
DeactDate DATETIME NULL,
BillDateTimeID BIGINT NOT NULL,
CustID INT NOT NULL,
ParentID INT NOT NULL
);
create table dimCust
(
CustID INT NOT NULL PRIMARY KEY,
CustName varchar(150) NOT NULL
);
create table dimParent
(
ParentID INT NOT NULL PRIMARY KEY,
ParentName varchar(100) NOT NULL
);
create table dimDateTime
(
DateTimeID BIGINT NOT NULL PRIMARY KEY
);
Tablolar ve örnek verilerle birlikte SQL Fiddle .
factStats
Tablo için FKS vardır DevID
, CustID
, BillDateTimeID
, ve ParentID
. Sahip olduğumuz istek ya hesapla etmektir veya saklamak Top 10 Parents
için her BillDateTimeID
dayanan TotalActive
VE aşağıdakine benzer bir toplu kategoride ilk 10'a giren değil herşeyi içerir:
+----------------+------------+------+
| BillDateTimeID | Parent | Rank |
+----------------+------------+------+
| 20140801 | Jim | 1 |
| 20140801 | Bob | 2 |
| 20140801 | All Others | 3 |
+----------------+------------+------+
Bunu, pencereleme işlevlerini kullanarak SQL'de kolayca başarabilirim ancak bunu SSAS için yeniden oluşturmaya çalışmak zordu. SQL'de sonucu şu sonucu elde ederiz:
;with Total as
(
select
ParentID,
BillDateTimeID,
sum(case when DeactDate is null then 1 else 0 end) TotalActive
from factStats
group by ParentID, BillDateTimeID
),
PRank as
(
select
ParentID,
BillDateTimeID,
TotalActive,
row_number() over(partition by BillDateTimeID
order by TotalActive desc) pr
from total
)
select
parentid,
BillDateTimeID,
TotalActive,
pr
from prank
where pr <= 2
union all
select
0,
BillDateTimeID,
sum(TotalActive) TotalActive,
3
from prank
where pr > 2
group by BillDateTimeID
order by BillDateTimeID desc, pr;
Sonucu elde etmek için birkaç farklı yol denedim, ancak her birinin bir sorunu var. Denemelerim aşağıda.
Başlangıçta, bir MDX sorgusu kullanarak veriyi biraz elde etmeyi başardım, ancak daha sonra bunun tablo modelimize nasıl dahil edileceği hakkında hiçbir fikrim yoktu. Başvuru için MDX sorgusu:
with
set [Top10Parent] AS
(
(TOPCOUNT({ORDER(({[Parent].[Parent Name].[Parent Name]}),
([Measures].[Total Count]), BDESC)}, 10))
)
MEMBER [Parent].[Parent Name].[Others] AS
(
AGGREGATE(EXCEPT([Parent].[Parent Name].[Parent Name], [Top10Parent]))
)
select
[Measures].[Total Count] on columns,
{[Top10Parent]}+ {[Parent].[Parent Name].[Others]} on Rows
from [OurModel]
where {[Date and Time].[Month and Year].[Month and Year].[Jul 2014]};
Tabii ki, bu da bana her ay değil, sadece bir ay için sonuç verdi.
MDX sorgusunun işe yaramayacağını fark ettiğimde, factStats
tablomuzu Top 10 ve toplanan değerlerin işaretlenmesi için yeni bir sütun içerecek şekilde değiştirerek başladım .
alter table factStats
add Top10ParentID INT NOT NULL
constraint DF_factStats default (0);
Varsayılan kısıt, ilk 10 için "Yuvarlandı" değerimize başvuruyor.
Deneme # 1: ParentID, isim ve Sıralamayı saklamak için yeni ilk 10 tablo oluşturdum:
create table dimTop10Parent
(
Top10ParentID INT NOT NULL PRIMARY KEY,
ParentName varchar(100) NOT NULL,
Parent_Rank INT NOT NULL
);
Bu tablo, modelimizi, sahip oldukları Toplam Aktif öğelere dayanarak yeni En İyi 10 Ebeveyn ile her yenilediğimizde doldurulacaktır. Parent_Rank
Kolon daha sonra bizim tablo modelinde gizli ve sıralama için özel olarak kullanılır. Bu harika çalışıyor, ancak bir aydan aya dayalı olmadığından tarihsel olarak İlk 10'a girme yeteneğine sahip değiliz.
Girişimi # 2: ilk 10 depolamak için yeni bir tablo oluşturun, ancak asıl anahtar, hem Top10ParentID hem de bir BillingDateTimeID içerir.
create table dimTop10Parent
(
Top10ParentID INT NOT NULL,
ParentName varchar(100) NOT NULL,
Parent_Rank INT NOT NULL,
BillDateTimeID BIGINT NOT NULL
);
Bununla ilgili sorun, tabular modelde dimTop10Parent'teki iki parçalı PK ile StatStats single FK arasında bir ilişki oluşturamayız.
Deneme # 3: Yeni tabloyu oluşturun, ancak PK olarak bir kimlik kullanın.
create table dimTop10Parent
(
Top10ID INT IDENTITY NOT NULL PRIMARY KEY,
Top10ParentID INT NOT NULL,
ParentName varchar(100) NOT NULL,
Parent_Rank INT NOT NULL,
BillDateTimeID BIGINT NOT NULL
);
factStats
Tablo depolayacak Top10ID
her satır için benzersiz olacaktır değer. Bunun sorunumu çözeceğini düşünmüştüm, fakat çözmedi çünkü Parent_Rank
modelde artık sıralama yapamayız , bir hata veriyor:
ParentName öğesinde ParentName öğesinde en az bir değer Parent_Rank öğesinde birden çok farklı değer bulunduğundan ParentName, Parent_Rank öğesine göre sıralanamıyor. Örneğin, [Şehir] 'i [Bölge]' ye göre sıralayabilirsiniz, çünkü her şehir için yalnızca bir bölge vardır, ancak her bölge için birden fazla şehir olduğundan [Bölge] 'yi [Şehir]' e göre sıralayamazsınız.
Örnek verileri kullanarak, nihai sonuç, buna benzer olmalıdır (bu, 3. sırayı toplayan Top 2’yi gösterir):
| PARENTNAME | BILLDATETIMEID | TOTALACTIVE | PR |
|------------|----------------|-------------|----|
| FDN | 201408010000 | 11 | 1 |
| FDO | 201408010000 | 3 | 2 |
| All Others | 201408010000 | 5 | 3 |
| FDN | 201407010000 | 12 | 1 |
| EVOD | 201407010000 | 2 | 2 |
| All Others | 201407010000 | 5 | 3 |
Bu noktada, bu son sonucun nasıl alınacağına dair bir zararım var. Bunu elde etmek için gerektiği kadar ben DAX formülleri kullanarak sıralaması hakkında okudum ben vs bir formül, ölçü kullanarak modeli değiştirebilir, tablolar değiştirebilir 1 , 2 , 3 ama başım Pandion'un olamaz sonucu doğru bir şekilde alabilmeleri için yeterli.
Bu İlk 10'u herhangi bir ay için nasıl hesaplayabilirim / saklayabilirim ve tablo modelimizde gerektiğinde verileri ekleyebilir miyim?