Bir tablo modelinde ilk 10 nasıl hesaplanır / depolanır?


23

Yakın zamanda bir SSAS tablo modeli oluşturduk, böylece kullanıcılarımız PowerView üzerinden erişebilirler. TotalActiveItemsBir 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 .

factStatsTablo için FKS vardır DevID, CustID, BillDateTimeID, ve ParentID. Sahip olduğumuz istek ya hesapla etmektir veya saklamak Top 10 Parentsiçin her BillDateTimeIDdayanan 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;

SQL Keman Demosu .

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, factStatstablomuzu 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_RankKolon 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
);

factStatsTablo depolayacak Top10IDher satır için benzersiz olacaktır değer. Bunun sorunumu çözeceğini düşünmüştüm, fakat çözmedi çünkü Parent_Rankmodelde 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?

Yanıtlar:


1

Benzer bir senaryo vardı ve aşağıdaki DAX sorgusunu kullandım ...

İlk önce, basitleştirmek için DAX içinde kullanılacak bir ölçü tanımladım, böylece formülü tekrarlamak zorunda kalmayacağım. Sonra, TOPN formülünü tekrarlamak için oluşturmak için kullandım:

define measure TableInTabular[NameOfTheMeasure] = COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)
evaluate
 (
  addcolumns
   (  
    filter
     (  
      generate
        (  
         VALUES(DatesTableName[Month]),  
         TOPN (10, VALUES(TableInTabular[ParentID]),TableInTabular[NameOfTheMeasure],0)
        ),
        TableInTabular[NameOfTheMeasure]>0
      ),
      "ActiveCount (or how you want to call this Column)",
      TableInTabular[NameOfTheMeasure]  
    )  
 )  
order by DatesTableName[Month] asc, 
TableInTabular[NameOfTheMeasure] desc

Yukarıdakilerle birlikte her ayın başında en iyi 10 ParentID ve Ölçüme sahip olmalısınız. "TableInTabular" ifadesini, verilerinizin bulunduğu tabular tablo adınızla ve tarih tablosunun adıyla "DatesTableName" yazmanız yeterlidir.

Lütfen sorunuzu yanlış anladıysam ve yardımcı olacağını umarsam ...


1
Cevabınız için teşekkürler, bununla ilgili hala bazı sorunlar var. Öncelikle, bunu SSMS'de kullanabilirim, ancak bu bizim tablo modelimizde konuşlandırılıyor, böylece kullanıcılarımız PowerView aracılığıyla erişebiliyor - herhangi bir sorgu yazmıyorlar - bu sadece mevcut olması gerekiyor. İkincisi, yanlış bir şey yapmadığım sürece, tabular modelinde Visual Studio aracılığıyla izin verilen bir değerlendirme veya sıra yoktur - bunun işlev olarak bir seçeneği yoktur. Üçüncüsü, bu sorgu sadece İlk 10'a döner, ayrıca toplanan verilere ya da onu elde etmek için bir yola ihtiyacım var. Bununla birlikte oynamaya devam edeceğim.
Taryn
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.