Bagaimana cara menghitung / menyimpan 10 besar dalam model tabel?

23

Kami baru-baru ini membuat model tabel SSAS sehingga pengguna kami dapat mengaksesnya melalui PowerView. Kami memiliki ukuran pada salah satu tabel fakta kami untuk mendapatkan TotalActiveItemsmenggunakan rumus:

TotalActive:=COUNTAX(FILTER('Stats', ISBLANK([DeactDate]) = TRUE), 1)

Ini berfungsi dengan baik sesuai kebutuhan, tetapi sekarang kami memiliki permintaan untuk mendapatkan 10 orang tua terbaik untuk setiap bulan di TotalActive.

Untuk referensi, berikut adalah bagian dari model kami:

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
);

SQL Fiddle dengan tabel dan sampel data.

The factStatstabel memiliki FK ke DevID, CustID, BillDateTimeID, dan ParentID. Permintaan yang kami miliki adalah menghitung atau menyimpan Top 10 Parentsmasing-masing BillDateTimeIDberdasarkan TotalActive DAN termasuk semua yang tidak termasuk dalam 10 Besar dalam kategori yang digulung mirip dengan yang berikut:

+----------------+------------+------+
| BillDateTimeID |   Parent   | Rank |
+----------------+------------+------+
|       20140801 | Jim        |    1 |
|       20140801 | Bob        |    2 |
|       20140801 | All Others |    3 |
+----------------+------------+------+

Saya dapat dengan mudah mencapai ini dalam SQL menggunakan fungsi windowing tetapi mencoba mereproduksi ini untuk SSAS sudah sulit. Dalam SQL, kami akan mendapatkan hasilnya menggunakan:

;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;

Demo SQL Fiddle .

Saya sudah mencoba beberapa cara berbeda untuk mendapatkan hasilnya tetapi masing-masing memiliki masalah. Upaya saya di bawah.

Awalnya, saya agak bisa mendapatkan data menggunakan permintaan MDX tetapi kemudian tidak tahu bagaimana memasukkan ini ke dalam model tabular kami. Permintaan MDX untuk referensi adalah:

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]};

Tentu saja, ini juga hanya memberi saya hasilnya selama satu bulan, tidak setiap bulan.

Ketika saya menyadari bahwa kueri MDX tidak berfungsi, saya mulai dengan mengubah factStatstabel kami untuk menyertakan kolom baru untuk menandai item di 10 Besar dan dalam nilai yang digulung.

alter table factStats
    add Top10ParentID INT NOT NULL
    constraint DF_factStats default (0);

Batasan standar merujuk nilai "Rolled Up" kami untuk Top 10.

Mencoba # 1: Saya membuat tabel Top 10 baru untuk menyimpan ParentID, nama dan Pangkat:

create table dimTop10Parent
(
    Top10ParentID INT NOT NULL PRIMARY KEY,
    ParentName varchar(100) NOT NULL,
    Parent_Rank INT NOT NULL
);

Tabel ini kemudian akan diisi setiap kali kita me-refresh model kita dengan 10 Orang Tua Top baru berdasarkan total Aktif item yang mereka miliki. The Parent_Rankkolom kemudian disembunyikan dalam model tabular kami dan digunakan secara eksklusif untuk menyortir. Ini bekerja dengan baik, kecuali kita tidak memiliki kemampuan untuk secara historis mendapatkan Top 10 karena tidak didasarkan pada basis bulan ke bulan.

Percobaan # 2: Buat tabel baru untuk menyimpan Top 10 tetapi PRIMARY KEY akan menyertakan Top10ParentID dan BillingDateTimeID.

create table dimTop10Parent
(
    Top10ParentID INT NOT NULL,
    ParentName varchar(100) NOT NULL,
    Parent_Rank INT NOT NULL,
    BillDateTimeID BIGINT NOT NULL
);

Masalahnya adalah kita tidak dapat membuat hubungan antara factStats FK tunggal dengan dua bagian PK di dimTop10Parent dalam model tabular.

Percobaan # 3: Buat tabel baru tetapi gunakan identitas sebagai PK.

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
);

The factStatsmeja akan menyimpan Top10IDnilai yang akan menjadi unik untuk setiap baris. Saya pikir ini akan menyelesaikan masalah saya tetapi, itu bukan karena kita tidak bisa lagi mengurutkan Parent_Rankdalam model, itu membuat kesalahan:

Tidak dapat mengurutkan ParentName oleh Parent_Rank karena setidaknya satu nilai di ParentName memiliki beberapa nilai yang berbeda di Parent_Rank. Misalnya, Anda dapat mengurutkan [Kota] berdasarkan [Wilayah] karena hanya ada satu wilayah untuk setiap kota, tetapi Anda tidak dapat mengurutkan [Wilayah] berdasarkan [Kota] karena ada beberapa kota untuk setiap wilayah.

Dengan menggunakan data sampel, hasil akhir harus sama dengan (ini menunjukkan Top 2 dengan ke-3 digulung):

| 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 |

Pada titik ini, saya bingung bagaimana mendapatkan hasil akhir ini. Saya dapat mengubah tabel sesuai kebutuhan untuk mendapatkannya, saya dapat mengubah model dengan menggunakan rumus, ukuran, dll. Saya telah membaca tentang pemeringkatan menggunakan rumus DAX 1 , 2 , 3 tapi sepertinya saya tidak bisa membungkukkan kepala saya mereka cukup untuk bisa mendapatkan hasilnya secara akurat.

Bagaimana saya bisa menghitung / menyimpan Top 10 ini untuk setiap bulan dan masih dapat melakukan splice data sesuai kebutuhan dalam model tabel kami?

Taryn
sumber

Jawaban:

1

Saya memiliki skenario yang sama dan menggunakan kueri DAX berikut ...

Pertama, untuk membuatnya sederhana, saya menetapkan ukuran untuk digunakan di dalam DAX jadi saya tidak perlu mengulangi rumus. Lalu saya menggunakan menghasilkan untuk beralih pada rumus TOPN:

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

Dengan yang di atas, Anda harus memiliki 10 ParentID dan Pengukuran teratas setiap bulan. cukup ganti "TableInTabular" dengan nama tabel tabular tempat Anda memiliki data dan "DatesTableName" dengan nama tabel tanggal.

Tolong beri tahu saya jika saya salah mengerti pertanyaan Anda dan harap ini membantu ...

Alejandro Pelc
sumber
1
Terima kasih atas jawabannya, masih ada beberapa masalah dengan ini. Pertama, saya dapat menggunakan ini di dalam SSMS tetapi ini sedang digunakan ke dalam model tabular kami sehingga pengguna kami dapat mengaksesnya melalui PowerView - mereka tidak akan menulis pertanyaan apa pun - ini hanya perlu tersedia. Kedua, Kecuali saya melakukan sesuatu yang salah, tidak ada evaluasi atau urutan dengan diizinkan dalam model tabel melalui Visual Studio - tidak ada opsi untuk ini sebagai fungsi. Ketiga, permintaan ini hanya mengembalikan Top 10, saya juga membutuhkan data yang digulung atau beberapa cara untuk mendapatkannya. Saya akan terus bermain-main dengan ini.
Taryn