フィルタおよびリストを含む KPI の定義
ここでは、フィルタおよびリストを含む Business Intelligence KPI を定義するオプションを説明します。
このページを読む前に、"基本的な KPI の定義" を参照してください。高度な KPI の詳細は、"高度な KPI の定義" を参照してください。
KPI には、アクションも定義できます。"カスタム・アクションの定義" を参照してください。
"BI サンプルのアクセス方法" も参照してください。
フィルタの概要
通常のダッシュボードには、1 つ以上のフィルタ・コントロールが組み込まれ、ユーザはこれを使用してダッシュボードのウィジェットと対話します。通常、各フィルタ・コントロールは、ドロップダウン・リストとして表示されます。フィルタで、ウィジェットによって表示されるデータをフィルタ処理できます。または、他の方法でデータ・ソースに影響を与えることができます。
ピボット・テーブルでは、キューブまたはサブジェクト領域の任意のレベルをフィルタとして使用できます。ただし、KPI の場合、既定ではフィルタは定義されていません。フィルタを KPI に追加するには、以下のシステムを使用します。
-
各フィルタを定義します。すなわち、フィルタ・リストのフィルタ名と項目を指定します。
ピボット・テーブルによって提供されるフィルタを使用する場合は、この手順をスキップできます。
-
プログラムによって、KPI クエリでフィルタを使用するように指定します。そのためには、KPI にコールバック・メソッドを実装し、ハードコードされたクエリをオーバーライドするようにします。このメソッド内で、選択したフィルタ値にアクセスできます。
一般的な例では、クエリで使用されるレコードを制限する WHERE 節 (MDX クエリでは %FILTER) を追加します。その後でユーザがダッシュボードを更新すると、クエリが再実行され、その結果が表示されます。
KPI クエリは自身で構成するので、より汎用的にフィルタを使用することができます。つまり、クエリの WHERE (または %FILTER) 節に作用するフィルタ選択を使用することは、必須ではありません。極端な例として、フィルタによってオプション 1、2、および 3 が表示されるとします。KPI はクエリのバージョン 1、2、または 3 を実行できますが、これらがまったく別のバージョンである場合もあります。別の例として、フィルタでメジャー名のリストが表示され、KPI がそのクエリに選択されたメジャーを組み込む場合もあります。
相互運用可能なフィルタの作成
ダッシュボードに KPI とピボット・テーブルの両方を追加して、スコアカード、ピボット・テーブル・ウィジェット、または他のウィジェットに表示できます。ダッシュボード内では、複数のウィジェットに作用するように、フィルタを構成できます。
KPI とピボット・テーブルの両方に作用するフィルタを定義できます。
ピボット・テーブルは、次のサブセクションで説明する固有の構文で、フィルタ値を送受信します。相互運用可能なフィルタを作成するには、この要件を考慮する必要があります。2 つ目のサブセクションで、2 つの考えられる方法について説明します。
ピボット・テーブルのフィルタ構文
以下のテーブルは、ピボット・テーブルで使用および期待されるフィルタ構文を示しています。この構文は、あらゆる種類のダッシュボード・ウィジェットに表示されるピボット・テーブルに適用されます。
シナリオ | 構文 | 例 | |
---|---|---|---|
フィルタ名 | All | MDX レベル識別子 | [Region].[H1].[Country] |
フィルタ値 | ユーザが 1 つのメンバを選択する | そのレベルのメンバの MDX キー。これは &[keyval] 形式の式であり、keyval はメンバのキー値。 | &[USA] |
フィルタ値 | ユーザがメンバの範囲を選択する | 以下の形式の式 : &[keyval1]:&[keyval2] | &[2006]:&[2009] |
フィルタ値 | ユーザが複数のメンバを選択する | 以下の形式の式 (例) : {&[keyval1],&[keyval2]} | {&[2006],&[2007],&[2008]} |
フィルタ値 | ユーザが 1 つのメンバを選択して [除外] を選択する | 以下の形式の式 : %NOT&[keyval1] | %NOT &[2010] |
フィルタ値 | ユーザが複数のメンバを選択して [除外] を選択する | 以下の形式の式 (例) : %NOT{&[keyval1],&[keyval2} | %NOT {&[2006],&[2007]} |
オプションの %NOT 文字列を除いて、フィルタ名およびフィルタ値は大文字と小文字が区別されません。
相互運用可能なフィルタを作成する方法
KPI とピボット・テーブルの両方に作用可能なフィルタを作成する汎用的な方法として、以下の 2 つがあります。
-
ピボット・テーブルが要求する形式のフィルタを定義して使用する KPI を作成できます。
-
ピボット・テーブル形式から KPI クエリで必要な形式にフィルタ名と値を変換する KPI を定義できます。
これらの方法は、MDX ベースまたは SQL ベースのどちらの KPI でも使用できますが、SQL ベースの KPI を使用する場合は、値の変換により多くの処理が必要になります。
MDX の例は、サンプル・ダッシュボード Demo Filter Interoperability を参照してください。このダッシュボードは、1 番目の方法のデモです。このダッシュボードには、2 つのピボット・テーブル・ウィジェットが表示され、上側にピボット・テーブル、下側に KPI が表示されます。このダッシュボードの左側の [フィルタ] ワークリストには、以下のフィルタが含まれています。
-
Favorite Color フィルタは、上側のウィジェットの一部として構成されており、そのウィジェットに表示されるピボット・テーブルによって定義されています。
Favorite Color は、このピボット・テーブルの基となるキューブのレベルです。
-
Doctor Group フィルタは、下側のウィジェットの一部として構成されており、そのウィジェットに表示される KPI によって定義されています。
このフィルタは、この KPI 内にプログラムによって定義されています。このフィルタは、前のセクションで示されているピボット・テーブル形式の値を使用するように、定義されています。
どちらのフィルタの場合も、ターゲットは * (このダッシュボードのすべてのウィジェットを示します) です。試してわかるように、どちらのフィルタも、両方のウィジェットに作用します。
KPI には別のフィルタ (Yaxis) も含まれています。このフィルタは、KPI で使用する MDX クエリの y 軸を制御します。このフィルタは、ピボット・テーブルには作用しません。
これが作用する方法の詳細は、このページで後述する "その他の MDX KPI の例" を参照してください。
MDX ベースの KPI でのフィルタの定義
MDX ベースの KPI でフィルタを定義するには、以下の手順を実行します。
-
フィルタのリストを指定します。各フィルタには、論理名 (必須) および表示名 (既定では論理名と同じ) があります。
1 つのオプションは、フィルタのリストをハードコードすることです。そのためには、一連の <filter> 要素を <kpi> 要素に追加します。以下に例を示します。
<kpi name="sample KPI"...> <filter name="[aged].[h1].[age group]" displayName="Age Group"/> <filter name="[gend].[h1].[gender]" displayName="Gender"/> <filter name="[homed].[h1].[zip]" displayName="ZIP Code"/> ...
この例では、論理フィルタ名は MDX レベル識別子です。この方法で論理名を指定すると便利です (ただし、必須ではありません)。
代わりに、実行時にフィルタ名を指定することもできます。このページで後述する "フィルタ名および項目を定義するその他のオプション" を参照してください。
-
<filter> 要素を追加する場合、必要に応じて以下のオプションを指定します。
-
ユーザがフィルタ・リストから要素を 1 つのみ選択できるように設定できます (既定では複数の要素)。そのためには、<filter> 要素に multiSelect="false" を追加します。以下に例を示します。
<filter name="[homed].[h1].[zip]" displayName="ZipCode" multiSelect="false" />
複数選択を無効にすると、[除外] オプションも無効になります。
-
フィルタ項目が日数の場合、既定のドロップダウン・リストではなくカレンダー・コントロールを表示できます。そのためには、<filter> 要素に searchType="day" を追加します。以下に例を示します。
<filter name="[birthd].[h1].[day]" displayName="Day" filterProperty="Day" searchType="day"/>
-
他のフィルタを基にするフィルタを作成できます。そのためには、オプションの dependsOn 属性を使用します。以下に例を示します。
<filter name="[homed].[h1].[zip]" displayName="ZIP Code"/> <filter name="[homed].[h1].[city]" displayName="City" dependsOn="[homed].[h1].[zip]"/>
-
-
各フィルタにフィルタ項目を定義します。各フィルタ項目には、論理名 (必須) および表示名 (既定では論理名と同じ) があります。
論理名が MDX メンバのキーと同じだと便利です。そうでない場合、このページで後述するように、フィルタ節を構築するためにより多くの作業が必要になります。
1 つ目のオプションは、%OnGetFilterMembers() メソッドを実装する方法です。フィルタの論理名が MDX レベル識別子の場合、以下の単純な実装を使用できます。
ClassMethod %OnGetFilterMembers(pFilter As %String, Output pMembers As %List,pSearchKey As %String = "") As %Status { set status = $$$OK try { do ..%GetMembersForFilter("Patients.cube",pFilter,.pMembers,pSearchKey) } catch(ex) { set status = ex.AsStatus() } quit status }
単純に Patients をキューブの名前に置き換えます。以下に例を示します。
do ..%GetMembersForFilter("YourCube.cube",pFilter,.pMembers,pSearchKey)
%OnGetFilterMembers() の詳細は、最初のサブセクションを参照してください。ここに示す例では、%GetMembersForFilter() メソッドを使用します。詳細は、2 番目のサブセクションを参照してください。
代わりに、フィルタ項目をハードコードできます。このページで後述する "フィルタ名および項目を定義するその他のオプション" を参照してください。
-
クエリを変更し、ユーザが選択した値を使用します。このページで後述する "MDX クエリを変更してフィルタ値を使用する" を参照してください。
%OnGetFilterMembers() の詳細
KPI クラスで、%OnGetFilterMembers() メソッドを実装する場合、以下のシグニチャを使用します。
classmethod %OnGetFilterMembers(pFilter As %String, Output pMembers As %List, pSearchKey As %String = "") as %Status
以下は、この指定の説明です。
-
pFilter は、フィルタの論理名です。
-
pMembers は、$LISTBUILD リストのメンバを指定します。このリストには、論理名と表示名の両方が含まれます。詳細は、%DeepSee.KPIOpens in a new tab のクラスリファレンスを参照してください。
-
pSearchKey は、ユーザが入力した検索キーです。
使用するクエリのタイプと関係なく、任意の KPI でこのメソッドを使用できます。
フィルタの論理名が MDX レベル識別子の場合、前述の単純な実装を使用できます。そうでない場合、メンバを取得するためにより多くの作業が必要です。例えば、このページで後述する "カスタム・ロジックを使用して実行時にフィルタ項目のリストを構築" を参照してください。
%GetMembersForFilter() の詳細
KPI クラスでは、以下のシグニチャを使用する %GetMembersForFilter() メソッドを使用できます。
classmethod %GetMembersForFilter(pCube As %String, pFilterSpec As %String, Output pMembers, pSearchKey As %String = "") as %Status
以下は、この指定の説明です。
-
pCube は、キューブの論理名に .cube を付加した名前です。
-
pFilterSpec は MDX レベル識別子です (例えば、"[DateOfSale].[Actual].[YearSold]")。
-
pMembers は、出力パラメータとして返される、%OnGetFilterMembers() で必須の形式のメンバのリストです。このリストでは、フィルタ項目はメンバ・キーです。
-
pSearchKey は、ユーザが入力した検索キーです。
このメソッドは、SQL ベースの KPI よりも MDX ベースの KPI で便利です。SQL ベースの KPI では、フィルタ値をクエリでの使用に適した形式に変換する必要があります。
SQL ベースの KPI でのフィルタの定義
SQL ベースの KPI でフィルタを定義するには、以下の手順を実行します。
-
フィルタのリストを指定します。各フィルタには、論理名 (必須) および表示名 (既定では論理名と同じ) があります。
1 つのオプションは、<kpi> 要素の <filter> 要素を指定することです。前のセクションを参照してください。
代わりに、実行時にフィルタ名を指定することもできます。このページで後述する "フィルタ名および項目を定義するその他のオプション" を参照してください。
-
各 <filter> 要素内で、必要に応じて以下の multiSelect、searchType、および dependsOn の各属性を指定します。前のセクションを参照してください。
-
各フィルタにフィルタ項目を定義します。各フィルタ項目には、論理名 (必須) および表示名 (既定では論理名と同じ) があります。
1 つのオプションは、このページで前述した %OnGetFilterMembers() メソッドを実装することです。
代わりに、フィルタ項目をハードコードできます。このページで後述する "フィルタ名および項目を定義するその他のオプション" を参照してください。
-
クエリを変更し、ユーザが選択した値を使用します。このページで後述する "SQL クエリを変更してフィルタ値を使用する" を参照してください。
フィルタ名および項目を定義するその他のオプション
このセクションでは、フィルタ名およびフィルタ項目を定義するその他のオプションについて説明します。以下のトピックについて説明します。
実行時のフィルタ名の指定
フィルタ名を定義する最も簡単な方法は、このページで前述したようにフィルタ名をハードコードすることです。その他のオプションは、実行時に定義することです。そのためには、KPI クラスの %OnGetFilterList() メソッドをオーバーライドします。このメソッドには、以下のシグニチャがあります。
classmethod %OnGetFilterList(Output pFilters As %List,pDataSourceName As %String = "") As %Status
pFilters は以下のノードの配列です。
-
pFilters — フィルタ数を指定します。
-
pFilters(n) — n 番目のフィルタの詳細を指定します。これは、以下の項目で構成される $LISTBUILD リストです。
-
フィルタの論理名に等しい文字列。
-
フィルタの表示名に等しい文字列。
-
フィルタ・プロパティに等しい文字列。既定値はフィルタの論理名です。
-
このフィルタで複数選択が有効かどうかを示す 1 または 0。1 を使用すると複数選択は有効、0 を使用すると無効。
-
pDataSourceName は、将来使用するためのものです。
例えば、以下の %OnGetFilterList() は New Filter という名前のフィルタを追加します。
ClassMethod %OnGetFilterList(Output pFilters As %List, pDataSourceName As %String = "") As %Status
{
set newfilter=$LB("New Filter","New Filter Display Name",,0)
set pFilters($I(pFilters))=newfilter
}
別の例として、以下の %OnGetFilterList() は、ユーティリティ・メソッドを使用して、Patients キューブのすべてのレベルをフィルタとして定義します。ユーティリティ・メソッド %GetFiltersForDataSource() (%DeepSee.Dashboard.UtilsOpens in a new tab 内) は、%OnGetFilterList() で必要な形式でフィルタのリストを返します。
ClassMethod %OnGetFilterList(Output pFilters As %List, pDataSourceName As %String = "") As %Status
{
set tSC = ##class(%DeepSee.Dashboard.Utils).%GetFiltersForDataSource("patients.cube",.tFilters)
quit:$$$ISERR(tSC)
set i = ""
for {
set i = $order(tFilters(i), 1, data)
quit:i=""
set pFilters($i(pFilters)) = $lb($lg(data,2), $lg(data,1),,1)
}
quit $$$OK
}
valueList 属性を使用したフィルタ項目のリストのハードコード
フィルタ項目のリストを構築する別の方法は、<filter> 要素の valueList 属性を指定することです。フィルタ項目の論理名のコンマで区切られたリストを使用します。このリストの順序によって、フィルタがフィルタ項目のリストを制御する順序が決まります。
以下に例を示します。
<filter name="ZipCode"
valueList="&[36711],&[34577],&[38928],&[32006],&[32007]"
displayList="36711,34577,38928,32006,32007"
/>
この属性は、sql 属性よりも優先されます。
この属性を指定する場合、上の例に示すように、displayList 属性も指定できます。指定する場合、表示名のコンマで区切られたリストを使用する必要があります。この属性を指定しない場合、論理名が表示名としても使用されます。
sql 属性を使用したフィルタ項目のリストの取得
フィルタ項目のリストを構築する別の方法は、<filter> 要素の sql 属性を指定することです。指定した場合、これは SQL クエリにする必要があります。このクエリは、1 列または 2 列を返すことができます。返されるデータセットの最初の列は、フィルタ項目の論理名を提供する必要があります。2 番目の列を含める場合、これは対応する表示名を提供します。2 番目の列を含まない場合、論理名が表示名としても使用されます。
以下に例を示します。
<filter name="ZipCode1" sql="SELECT DISTINCT PostalCode FROM BI_Study.City"/>
sql 属性を指定する場合は、displayList 属性および valueList 属性は指定しないでください (前のサブセクションを参照してください)。
カスタム・ロジックを使用して実行時にフィルタ項目のリストを構築
フィルタ項目のリストを構築する別の方法は、%OnGetFilterMembers() および独自のロジックを実装し、リストを作成することです。以下に例を示します。
ClassMethod %OnGetFilterMembers(pFilter As %String, Output pMembers As %List, pSearchKey As %String = "") As %Status
{
Set status = $$$OK
Try {
If (pFilter = "AgeGroup") {
set pFilterSpec="[AgeD].[h1].[Age Group]"
} Elseif (pFilter="Gender") {
set pFilterSpec="[GenD].[h1].[Gender]"
} Elseif (pFilter="ZipCode") {
set pFilterSpec="[HomeD].[h1].[ZIP]"
}
do ##class(%DeepSee.KPI).%GetMembersForFilter("Patients",pFilterSpec,.pMembers,pSearchKey)
}
Catch(ex) {
Set status = ex.AsStatus()
}
Quit status
}
別の方法として、レベル・メンバを保持するディメンジョン・テーブルでクエリを実行することができます。(ディメンジョン・テーブルの詳細は、"ファクト・テーブルおよびディメンジョン・テーブルの詳細" を参照してください。)以下に例を示します。
ClassMethod %OnGetFilterMembers(pFilter As %String, Output pMembers As %List, pSearchKey As %String = "") As %Status
{
set status = $$$OK
try {
if (pFilter = "AgeGroup") {
//get values from level table
set sql = "SELECT DISTINCT DxAgeGroup FROM BI_Model_PatientsCube.DxAgeGroup"
set stmt = ##class(%SQL.Statement).%New()
set status = stmt.%Prepare(sql)
if $$$ISERR(status) {write "%Prepare failed:" do $SYSTEM.Status.DisplayError(status) quit}
set rs = stmt.%Execute()
if (rs.%SQLCODE '= 0) {write "%Execute failed:", !, "SQLCODE ", rs.%SQLCODE, ": ", rs.%Message quit}
while(rs.%Next()) {
set display=rs.DxAgeGroup
set actual="&["_display_"]"
set pMembers($I(pMembers)) = $LB(display,actual)
}
if (rs.%SQLCODE < 0) {write "%Next failed:", !, "SQLCODE ", rs.%SQLCODE, ": ", rs.%Message quit}
}
}
catch(ex) {
set status = ex.AsStatus()
}
quit status
}
この例では pSearchKey 引数を使用しません。
MDX クエリを変更してフィルタ値を使用する
MDX ベースの KPI では、クエリを変更してフィルタを使用するには、%OnGetMDX() メソッドを実装します。スタジオで KPI ウィザードを使用して、ソース・タイプとして MDX を選択する場合、生成される KPI クラスには、このメソッドの以下のスタブ定義が含まれます。これを開始点として使用できます。
/// Return an MDX statement to execute.
Method %OnGetMDX(ByRef pMDX As %String) As %Status
{
Quit $$$OK
}
変数 pMDX には、<kpi> の mdx 属性で指定される MDX クエリが格納されます(この属性を指定しなかった場合、pMDX は Null になります)。
このメソッドを実装する場合、以下の手順を実行します。
-
初期クエリがない場合、変数 pMDX の初期値を指定します。これは MDX SELECT クエリです。
"基本的な KPI の定義" で説明したように、mdx 属性でクエリを指定しない場合、初期クエリはありません。
-
該当するフィルタそれぞれを調べ、その値を取得します。
このためには、最初のサブセクションで説明したように、KPI インスタンスの %filterValues プロパティを使用します。
-
各フィルタ値を解析し、必要に応じて、MDX %FILTER 節で使用できる形式に変換します (これがフィルタを使用する方法の場合)。適切な形式をリストするテーブルは、2 番目のサブセクションを参照してください。
-
ニーズに合わせて、変数 pMDX を変更して、フィルタ値を使用します。最も一般的な状況では、以下のように NULL でない各フィルタに %FILTER 節を追加します。
%FILTER mdx_expression
ここで、mdx_expression は、前の手順で作成した、そのフィルタの式です。
または、式を結合する MDX タプル式を作成し、以下のように 1 つの %FILTER 節を追加します。
%FILTER tuple_expression
一般的ではない状況では、フィルタ値を使用して、別の方法でクエリ文字列を書き換えることができます。
-
$$$OK (または 1) を返します。
最後のサブセクションに例を示します。
フィルタ値へのアクセス
ユーザがフィルタ項目を選択すると、KPI インスタンスの %filterValues プロパティが設定されます。このプロパティは、システムによって以下のように作成されたオブジェクト (具体的には %ZEN.proxyObjectOpens in a new tab のインスタンス) です。
-
KPI のフィルタごとに、フィルタと同じ名前 (大文字と小文字が区別されます) のプロパティが 1 つあります。
例えば、KPI に filter1、filter2、および filter3 という名前のフィルタがある場合、KPI インスタンスの %filterValues プロパティには filter1、filter2、および filter3 という名前のプロパティがあります。
-
%filterValues のプロパティには、以下のテーブルに示す値が含まれます。
ユーザがフィルタで選択する対象 %filterValues.FilterName の値 留意事項 なし null 1 つの項目 item 複数の項目 {item1,item2} 複数選択がオフの場合には該当なし 1 つの項目と [除外] オプション %NOT item 複数選択がオフの場合には該当なし 複数の項目と [除外] オプション %NOT {item1,item2} 複数選択がオフの場合には該当なし 範囲 item1:item2 ピボット・テーブルで定義されるフィルタに対してのみ適用され、KPI に影響します
%FILTER で使用するためにフィルタ値を MDX 式に変換
以下のテーブルは、ユーザの選択に応じて、%FILTER 節での使用に適切な MDX 式をリストしています。
ユーザがフィルタで選択する対象 | 該当する MDX %FILTER 式 |
---|---|
なし | none (この場合、%FILTER 節を適用しません) |
1 つの項目 | [dimension].[hierarchy].[level].[member] |
1 つの項目と [除外] オプション | [dimension].[hierarchy].[level].[member].%NOT |
item1 および item2 | {item1,item2,...} (各 item の形式は [dimension].[hierarchy].[level].[member]) |
複数の項目と [除外] オプション | EXCEPT([dimension].[hierarchy].[level].MEMBERS,{item,item,item,...}) (各 item の形式は [dimension].[hierarchy].[level].[member]) |
範囲 | [dimension].[hierarchy].[level].[member]:[member] |
使用例は、サンプル・クラス BI.Utils.MDXAutoFiltersKPI のメソッド BuildString() を参照してください。
複数選択が無効になっている場合、EXCLUDE も無効になり、フィルタ値の使用できる形式が減ることに注意してください。この場合、クエリ構造は比較的単純です。
例
%OnGetMDX() の以下の実装は、複数選択が無効になっている KPI に適用されます。
Method %OnGetMDX(ByRef pMDX As %String) As %Status
{
if (..%filterValues."[aged].[h1].[age group]"'="")
{
set pMDX = pMDX _ " %FILTER [aged].[h1].[age group]." _..%filterValues."[aged].[h1].[age group]"
}
if (..%filterValues."[gend].[h1].[gender]"'="")
{
set pMDX = pMDX _ " %FILTER [gend].[h1].[gender]." _..%filterValues."[gend].[h1].[gender]"
}
if (..%filterValues."[homed].[h1].[zip]"'="")
{
set pMDX = pMDX _ " %FILTER [homed].[h1].[zip]." _..%filterValues."[homed].[h1].[zip]"
}
quit $$$OK
}
このメソッドは、区切りプロパティ名を使用しているため、読みにくい場合があります。メモ :
-
"[aged].[h1].[age group]" は、有効なプロパティ名です。
-
..%filterValues."[aged].[h1].[age group]" は、KPI インスタンスの %filterValues プロパティの "[aged].[h1].[age group]" プロパティへの参照です。
SQL クエリを変更してフィルタ値を使用する
SQL ベースの KPI では、クエリを変更してフィルタを使用するには、%OnGetSQL() メソッドを実装します。スタジオで KPI ウィザードを使用して、ソース・タイプとして SQL を選択する場合、生成される KPI クラスには、このメソッドの以下のスタブ定義が含まれます。これを開始点として使用できます。
/// Return an SQL statement to execute.
Method %OnGetSQL(ByRef pSQL As %String) As %Status
{
Quit $$$OK
}
変数 pSQL には、<kpi> の sql 属性で指定される SQL クエリが格納されますこの属性を使用していない場合、pSQL は Null です。
このメソッドを実装する場合、以下の手順を実行します。
-
初期クエリがない場合、変数 pSQL の初期値を指定します。これは SQL SELECT クエリです。
"基本的な KPI の定義" で説明したように、sql 属性でクエリを指定しない場合、初期クエリはありません。
-
該当するフィルタそれぞれを調べ、その値を取得します。このオプションは以下のとおりです。
-
%GetSQLForFilter() メソッドを使用します。これは、SQL クエリの WHERE 節で使用する便利な形式で値を返します。最初のサブセクションを参照してください。
-
前のセクションで説明したように、KPI インスタンスの %filterValues プロパティを使用します。
-
-
ニーズに合わせて、変数 pSQL を変更して、フィルタ値を使用します。最も一般的な状況では、クエリを変更して SQL WHERE 節を組み込みます。
一般的ではない状況では、フィルタ値を使用して、別の方法でクエリ文字列を書き換えることができます。
-
$$$OK (または 1) を返します。
SQL ベースの KPI は 1000 行を超えることはできません。返される行数は自動的に制限されます。
%GetSQLForFilter()
SQL ベースの KPI では、クエリに組み込むのに便利な形式でフィルタ値にアクセスするメソッドを使用できます。
method %GetSQLForFilter(sql_field_reference,filter_name) As %String
現在のフィルタ選択を調べて、SQL クエリの WHERE 節で使用できる文字列を返します。
sql_field_expression は SQL フィールド名で、矢印構文を含むことができます。filter_name は、この KPI で定義されるフィルタの名前です。
例えば、以下のメソッド呼び出しを考えてみます。
..%GetSQLForFilter("City->Name","City")
以下のテーブルに、さまざまなシナリオでこのメソッド呼び出しによって返される値を示します。
シナリオ | メソッドによって返される値 |
---|---|
ユーザが PINE を選択する | City->Name = 'PINE' |
ユーザが MAGNOLIA で始まり PINE で終わる範囲を選択する | City->Name = ('MAGNOLIA':''PINE') |
ユーザが MAGNOLIA と PINE を選択する | City->Name IN ("MAGNOLIA','PINE') |
ユーザが PINE を選択して [除外] を選択する | City->Name <> 'PINE' |
ユーザが MAGNOLIA と PINE を選択して [除外] を選択する | City->Name NOT IN ('MAGNOLIA','PINE') |
SQL KPI の例 1
以下の例は、サンプル・クラス BI.Model.KPIs.DemoSQL のものです。この場合、フィルタは、GROUP BY 節と ORDER BY 節を SQL クエリに追加します。
Method %OnGetSQL(ByRef pSQL As %String) As %Status
{
//this is the start of the SQL query for this KPI
Set pSQL = "SELECT Count(*),AVG(Age) FROM BI_Study.Patient "
Set where = ""
//look at %filterValues to see if a filter has been applied to this KPI instance
If $IsObject(..%filterValues) {
If (..%filterValues.ZipCode'="")
{
// Call utility method that returns filter data in convenient format
Set sqlstring=..%GetSQLForFilter("HomeCity->PostalCode","ZipCode")
Set where = "WHERE "_sqlstring
}
}
Set groupby="GROUP BY HomeCity "
Set orderby="ORDER BY HomeCity "
// assemble the SQL statement
Set pSQL=pSQL_where_groupby_orderby
Quit $$$OK
}
SQL KPI の例 2
以下の例は、サンプル・クラス HoleFoods.KPISQL のものです。
Method %OnGetSQL(ByRef pSQL As %String) As %Status
{
If $IsObject(..%filterValues) {
Set tWHERE = ""
If (..%filterValues.City'="") {
Set tWHERE = tWHERE _ $S(tWHERE="":"",1:" AND ") _ " Outlet->City = '" _ ..%filterValues.City _"'"
}
If (..%filterValues.Product'="") {
Set tWHERE = tWHERE _ $S(tWHERE="":"",1:" AND ") _ " Product = '" _ ..%filterValues.Product _"'"
}
If (tWHERE'="") {
// insert WHERE clase within query
Set tSQL1 = $P(pSQL,"GROUP BY",1)
Set tSQL2 = $P(pSQL,"GROUP BY",2)
Set pSQL = tSQL1 _ " WHERE " _ tWHERE
If (tSQL2 '= "") {
Set pSQL = pSQL _ " GROUP BY" _ tSQL2
}
}
}
Quit $$$OK
}
この場合、KPI は、"基本的な KPI の定義" で説明したように、sql 属性内に初期クエリを定義します。%OnGetSQL() メソッドは、そのクエリを変更します。
その他の MDX KPI の例
このセクションでは、その他の MDX KPI の例について説明します。
DemoMDXAutoFilters KPI
サンプル・クラス BI.Model.KPIs.DemoMDXAutoFilters の KPI は単純ですが、特別なスーパークラスを使用します。
Class BI.Model.KPIs.DemoMDXAutoFilters Extends BI.Utils.MDXAutoFiltersKPI
{
Parameter CUBE = "PATIENTS";
Parameter DOMAIN = "PATIENTSAMPLE";
XData KPI [ XMLNamespace = "http://www.intersystems.com/deepsee/kpi" ]
{
<kpi name="DemoMDXAutoFilters" displayName="DemoMDXAutoFilters"
sourceType="mdx"
mdx="SELECT {[Measures].[%COUNT],[Measures].[Avg Age],[Measures].[Avg Allergy Count]} ON 0,
NON EMPTY [DiagD].[H1].[Diagnoses].Members ON 1 FROM [Patients]">
<property name="Patient Count" displayName="Patient Count" columnNo="1" />
<property name="Avg Age" displayName="Avg Age" columnNo="2" />
<property name="Avg Allergy Count" displayName="Avg Allergy Count" columnNo="3" />
</kpi>
}
}
このクラスは、直接フィルタを定義することも、直接フィルタ・メンバを定義することもなく、ハードコードされた MDX クエリのみを定義していることに注意してください。ただし、この KPI のテスト・ページを表示した場合、Patients キューブのすべてのレベルをフィルタとして使用でき、KPI は適切な %WHERE 節をクエリに追加します。以下に例を示します。
この KPI は、サンプル BI.Utils.MDXAutoFiltersKPI を拡張します。これは、フィルタを定義し、クエリを書き換えます。
このクラスには、以下のメソッドが存在します。
-
%OnGetFilterList() は、CUBE クラス・パラメータで指定されたキューブに定義されているすべてのレベルを取得します。
-
%OnGetFilterMembers() が実装されています。各レベルで、ピボット・テーブルで要求される形式で、レベル・メンバを取得します。このページで前述した "ピボット・テーブルのフィルタ構文" を参照してください。
-
インスタンス・メソッド FilterBuilder() は、キューブ・ベースのフィルタを繰り返し処理して、それぞれの現在の値を取得し、それらを結合して MDX %FILTER 節としての使用に適した 1 つの文字列を生成します。
-
%OnGetMDX() は、ハードコードされたクエリに %FILTER 節を追加します。
DemoInteroperability KPI
サンプル・クラス BI.Model.KPIs.DemoInteroperability の KPI は、前述の例より複雑です。このクラス内で、%OnGetFilterList() は、CUBE クラス・パラメータで指定されたキューブに定義されているすべてのレベルを取得します。次に、Yaxis という名前の別のフィルタを追加します。
ClassMethod %OnGetFilterList(ByRef pFilters As %List, pDataSourceName As %String = "") As %Status
{
//call method in superclass so we can get filters of the associated cube
set tSC=##super(.pFilters,pDataSourceName)
quit:$$$ISERR(tSC) tSC
//update pFilters array to include the custom filter
set pFilters($i(pFilters)) = $lb("Yaxis","Yaxis",,0)
quit $$$OK
}
%OnGetFilterMembers() が実装されています。フィルタ Yaxis の場合、このメソッドはメンバ・セットを提供します。他のフィルタの場合、ピボット・テーブルで要求される形式で、レベル・メンバを取得します。このページで前述した "ピボット・テーブルのフィルタ構文" を参照してください。このメソッドは、以下のとおりです。
ClassMethod %OnGetFilterMembers(pFilter As %String, Output pMembers As %List, pSearchKey As %String = "",
pDataSourceName As %String = "") As %Status
{
set pMembers=""
if (pFilter="Yaxis") {
set pMembers($I(pMembers))=$LB("Home City","[homed].[h1].[city]")
set pMembers($I(pMembers))=$LB("Favorite Color","[colord].[h1].[favorite color]")
set pMembers($I(pMembers))=$LB("Profession","[profd].[h1].[profession]")
set pMembers($I(pMembers))=$LB("Diagnoses","[diagd].[h1].[diagnoses]")
} else {
//call method in superclass so we can get filter members for the associated cube
do ..%GetMembersForFilter(..#CUBE,pFilter,.pMembers)
}
quit $$$OK
}
最後に、%OnGetMDX() は MDX クエリを構築します。Yaxis フィルタは、行に使用するレベルを決定します。このメソッドは、%FILTER 節をクエリに追加します。%FILTER 節は、前の例と同様に、キューブ・ベースの任意のフィルタを使用します。
Method %OnGetMDX(ByRef pMDX As %String) As %Status
{
set yaxis=", NON EMPTY [profd].[h1].[profession].MEMBERS ON 1"
//check custom filter value
if (..%filterValues."Yaxis"'="") {
set yaxis=", NON EMPTY "_..%filterValues.Yaxis_".MEMBERS ON 1"
}
set pMDX="SELECT {MEASURES.[%COUNT],MEASURES.[avg age]} on 0"_yaxis_" FROM "_..#CUBE
/// append a %FILTER clause to handle any other filter values
Set pMDX = pMDX _ ..FilterBuilder()
Quit $$$OK
}
KPI のリストの定義
リスト・オプションを含むように KPI を定義できます。この場合、KPI にフィルタも含まれる場合、リスト定義でフィルタ選択を考慮する必要があります。
リストを定義するために、KPI クラスに %OnGetListingSQL() メソッドを実装します。このメソッドには、以下のシグニチャがあります。
ClassMethod %OnGetListingSQL(ByRef pFilters As %String, ByRef pSelection As %String) As %String
このメソッドは、リスト・クエリのテキストを返します。引数は以下のとおりです。
-
pFilters は、現在のフィルタ値を格納する多次元配列です。この配列には以下のノードがあります。
ノード ノード値 pFilters(filter_name)。filter_name は、この KPI で定義されるフィルタの名前です。 このフィルタの現在の値 詳細は、"KPI フィルタの定義" を参照してください。
-
pSelection は、現在の選択に関する情報を格納する多次元配列です。この配列には以下のノードがあります。
ノード ノード値 pSelection("selectedRange") ピボットで形式 "startRow,startCol,endRow,endCol" (1-based) の文字列として現在選択されているセル。 pSelection("rowValues") 選択された行の値のコンマ区切りのリスト。これらの値では、コンマが円記号 (\) として表示されます。KPI のプロパティでこの値が構成されていない場合は、このノードには代わりに系列名が含まれます。 pSelection("sortColumn") リストの並べ替えに使用する列の番号を指定します。0 を使用すると並べ替えは行われません。 pSelection("sortDir") 並べ替えの方向を "ASC" または "DESC" で指定します。
このメソッドは、SQL SELECT クエリを返す必要があります。このクエリでは、他のリストと同様に、矢印構文および SQL 関数も使用できます。
または、%OnGetListingResultSet() メソッドをオーバーライドできます。オーバーライドする場合は、結果セットを作成して実行する必要があります。
例
以下の例は、HoleFoods.KPISQL からの抜粋です。
ClassMethod %OnGetListingSQL(ByRef pFilters As %String, ByRef pSelection As %String) As %String
{
Set tSQL = "SELECT TOP 1000 %ID,DateOfSale,Product FROM HoleFoods.SalesTransaction"
// apply sorting, if asked for
If (+$G(pSelection("sortColumn"))>0) {
Set tSQL = tSQL _ " ORDER BY " _ pSelection("sortColumn") _ " " _ $G(pSelection("sortDir"))
}
Quit tSQL
}