テーブルモデルのトップ10を計算/保存する方法は?


23

ユーザーがPowerView経由でアクセスできるように、SSASテーブルモデルを最近作成しました。TotalActiveItems式を使用して取得するファクトテーブルの1つにメジャーがあります。

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

これは必要に応じてうまくいきますが、今では毎月のトップ10の親を取得するリクエストがありTotalActiveます。

参考のため、ここにモデルの一部を示します。

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

factStats表には、へFKSを持っているDevIDCustIDBillDateTimeID、とParentID。我々が持っているという要求はどちらか計算するのですか保存Top 10 ParentsそれぞれにBillDateTimeID基づいてTotalActive 次のようなロールアップカテゴリーでトップ10にないすべてのものが含まれています。

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

ウィンドウ関数を使用してSQLでこれを簡単に実現できますが、SSASでこれを再現しようとするのは困難でした。SQLでは、次を使用して結果を取得します。

;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 Fiddleデモ

結果を得るためにいくつかの異なる方法を試しましたが、それぞれに問題がありました。私の試みは以下です。

最初は、MDXクエリを使用してデータをある程度取得できましたが、これを表形式モデルに組み込む方法がわかりませんでした。参照用のMDXクエリは次のとおりです。

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

もちろん、これは、毎月ではなく、1か月間の結果のみを提供しました。

MDXクエリが機能しないことに気付いたとき、factStatsテーブルを変更して新しい列を追加し、トップ10およびロールアップされた値のアイテムにフラグを立てることから始めました。

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

デフォルトの制約は、上位10の「ロールアップ」値を参照します。

試行#1: ParentID、名前、およびランクを保存する新しいTop 10テーブルを作成しました。

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

このテーブルは、所有するアクティブなアイテムの合計に基づいて、新しい上位10の親でモデルを更新するたびに作成されます。Parent_Rank次いで、カラムを、私たちの表形式のモデルに隠され、並べ替えのためにのみ使用されます。これはうまく機能しますが、月ごとに基づいていないため、歴史的にトップ10を取得することができません。

試行#2:上位10を保存する新しいテーブルを作成しますが、PRIMARY KEYにはTop10ParentIDとBillingDateTimeIDの両方が含まれます。

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

この問題は、factStatsシングルFKと、表形式モデルのdimTop10Parentの2つの部分PKの間に関係を作成できないことです。

試行#3:新しいテーブルを作成しますが、IDを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
);

factStatsテーブルが格納するTop10ID行ごとに一意であろう値。これで問題が解決すると思いましたParent_Rankが、モデル内でソートできなくなったため、エラーがスローされませんでした。

ParentNameの少なくとも1つの値がParent_Rankに複数の異なる値を持っているため、ParentNameをParent_Rankでソートできません。たとえば、各都市に1つの地域しかないため、[都市]を[地域]で並べ替えることができますが、各地域に複数の都市があるため、[都市]で[地域]を並べ替えることはできません。

サンプルデータを使用すると、最終結果は次のようになります(これは3番目のロールアップでトップ2を示しています)。

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

この時点で、私はこの最終結果を得る方法に途方に暮れています。私はそれを得るために、必要に応じて、私は式を用いてモデルを変更することができ、テーブルを変更対策、DAXの数式を使用してランク付けについてなどIまし読むことができます123、私は私の頭の周りを包むように見えることはできません結果を正確に取得するのに十分です。

どのようにしてこの月のトップ10を計算/保存し、表モデルで必要に応じてデータを接合することができますか?

回答:


1

同様のシナリオがあり、次のDAXクエリを使用しました...

まず、簡単にするために、DAX内で使用するメジャーを定義したので、式を繰り返す必要がありません。次に、生成を使用して、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

上記を使用すると、上位10のParentIDと各月ごとのメジャーが必要です。「TableInTabular」をデータがある表形式のテーブル名に、「DatesTableName」を日付表の名前に置き換えるだけです。

あなたの質問を誤解し、それが助けになることを願っている場合、私に知らせてください...


1
答えてくれて、これにはまだいくつかの問題があります。まず、SSMS内でこれを使用できますが、これは表形式モデルに展開されているため、ユーザーはPowerViewを介してアクセスできます-クエリを作成する必要はありません-これが利用できる必要があります。第二に、私が何か間違ったことをしていない限り、Visual Studioを介して表形式モデルで許可されている評価や順序はありません-関数としてのオプションはありません。第三に、このクエリは上位10件のみを返すので、ロールアップデータまたはそれを取得する何らかの方法も必要です。しかし、私はこれをいじり続けます。
タリン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.