クエリのフィルタ処理
ここでは、Business Intelligence MDX クエリ内のデータをフィルタ処理する方法を説明します。
"BI サンプルのアクセス方法" も参照してください。
WHERE 節の概要
MDX クエリ自体にフィルタ (WHERE 節) を含めることもできます。MDX クエリの WHERE 節は、一般にスライサ軸と呼ばれます。WHERE 節に含まれているメンバが 1 つのみの場合、アクセスされるのはキューブの 1 つのスライスのみになります。
例えば、以下のクエリを考えてみます。
SELECT {MEASURES.[%COUNT],MEASURES.[avg age]} ON 0, gend.gender.MEMBERS ON 1 FROM demomdx WHERE homed.redwood
Patient Count Avg Age
1 Female 536 36.70
2 Male 540 36.52
このクエリは、キューブの 1 つのスライス (出身地が Redwood の患者のスライス) にのみアクセスします。以下はその例です。
この場合、Redwood スライスは、クエリが考慮するキューブの唯一の部分です。
ただし、WHERE 節で 1 つのセットまたは 1 つのタプルが使用される場合には、スライサ軸という語句はそれほど役に立ちません。このような場合には、キューブが忠実にスライスされないためです。
WHERE 節でのセットの使用
より一般的には、WHERE 節には 1 つのメンバ式の代わりにセット式を含めることができます。この場合、MDX では論理 AND を使用してレコードを組み合わせます。例えば、以下のクエリでは、好きな色が赤である患者と男性患者のみを使用しています。
SELECT MEASURES.[%COUNT] ON 0, homed.city.MEMBERS ON 1 FROM demomdx WHERE{colord.red,gend.male}
%COUNT
1 Cedar Falls 66
2 Centerville 72
3 Cypress 76
4 Elm Heights 81
5 Juniper 74
6 Magnolia 63
7 Pine 71
8 Redwood 72
9 Spruce 58
この場合、クエリでは、2 つのメンバで構成されたセット {colord.red,gend.male} を使用しています。システムはファクト・テーブルにアクセスすると、colord.red に関連付けられたレコードと gend.male に関連付けられたレコードを検索し、それらのレコードをすべて使用します。
各セット要素は別のスライサ軸として使用され、(すべての %FILTER 節の) すべてのスライサ軸の結果がまとめて集約されます。これは軸のたたみ込みのプロセスです (フィルタはクエリ軸と見なされます)。軸のたたみ込みを実行すると、どのスライサ軸にも NULL の結果がないソース・レコードは複数回カウントされます。
軸のたたみ込みでは、キューブの定義での指定に従い、対象としているメジャーの集約メソッドに基づいて値が組み合わされます (ここの例では、%COUNT が追加されます)。
詳細は、"InterSystems Business Intelligence の実装" の "Business Intelligence クエリ・エンジンの仕組み" の項目にある "軸のたたみ込み" を参照してください。
次のセクションでは、さらに別の方法でクエリをフィルタ処理する方法について説明します。
WHERE 節でのタプルの使用
WHERE 節では、代わりに 1 つのタプルまたは一連のタプルを使用することもできます。以下はその例です。
SELECT MEASURES.[%COUNT] ON 0, NON EMPTY homed.city.MEMBERS ON 1 FROM demomdx
WHERE (aged.[age group].[60 +],gend.male)
%COUNT
1 Cedar Falls 7
2 Centerville 9
3 Cypress
12
4 Elm Heights 14
5 Juniper 8
6 Magnolia 9
7 Pine 7
8 Redwood 6
9 Spruce 2
別の例を示します。
WITH SET myset as '{(aged.[age group].[60 +],diagd.chd),(aged.[age group].[60+],diagd.asthma)}'
SELECT MEASURES.[%COUNT] ON 0, NON EMPTY homed.city.MEMBERS ON 1 FROM demomdx WHERE myset
%COUNT
1 Cedar Falls 5
2 Centerville 5
3 Cypress 8
4 Elm Heights 3
5 Juniper 3
6 Magnolia 5
7 Pine 2
8 Redwood 5
クエリ自体をフィルタ処理する場合は、NON EMPTY キーワードを使用して、NULL 以外の値だけをクエリが返すようにすると便利です。このキーワードは、NULL 値を返す可能性のあるセット式の先頭に含めます。以下はその例です。
SELECT MEASURES.[%COUNT] ON 0, NON EMPTY homed.city.MEMBERS ON 1 FROM demomdx
WHERE (aged.[age bucket].[30 to 39],diagd.chd)
%COUNT
1 Elm Heights 1
2 Magnolia 1
一方、NON EMPTY を使用しなかった場合、結果は以下のようになります。
SELECT MEASURES.[%COUNT] ON 0, homed.city.MEMBERS ON 1 FROM demomdx
WHERE (aged.[age bucket].[30 to 39],diagd.chd)
%COUNT
1 Cedar Falls *
2 Centerville *
3 Cypress *
4 Elm Heights 1
5 Juniper *
6 Magnolia 1
7 Pine *
8 Redwood *
9 Spruce *
%NOT 最適化
レベルの単一のメンバを除外することが必要な場合も多くあります。これを簡単に行うための方法として、InterSystems の拡張機能である %NOT 関数を使用できます。
SELECT aged.[age bucket].MEMBERS ON 1 FROM patients WHERE aged.[age group].[0 to 29].%NOT
1 0 to 9 *
2 10 to 19 *
3 20 to 29 *
4 30 to 39 166
5 40 to 49 139
6 50 to 59 106
7 60 to 69 86
8 70 to 79 62
9 80+ 41
%NOT 関数を使用するクエリは、EXCEPT を使用する同等のクエリよりも実行速度が速くなります。
%OR 最適化
多くの場合は、WHERE 節によって複数のメンバを表す必要があります。以下はその例です。
SELECT gend.MEMBERS ON 1 FROM patients WHERE {allerd.[ant bites],allerd.soy,allerd.wheat}
1 Female 56
2 Male 59
ただし、このクエリ構文では、システムがクエリの結果を複数回 (WHERE 節に含まれる項目ごとに 1 回) 評価してから、それらを結合することになります。そのため、実行時間が長くなる可能性や重複して項目をカウントする可能性があります (この例では、特定の患者が、WHERE 節のアレルギーごとに 1 回ずつ、合計 3 回カウントされることがあります)。
%OR 関数を使用して、このクエリを以下のように書き換えることができます。
SELECT gend.MEMBERS ON 1 FROM patients WHERE %OR({allerd.[ant bites],allerd.soy,allerd.wheat})
1 Female 55
2 Male 57
前よりも数が減っていることに注意してください。これは、このクエリでは患者を重複してカウントしていないからです。また、このクエリは前のクエリよりも高速です。
異なるレベルのメンバ (またはタプル) を含むセットで %OR を使用できます。以下はその例です。
SELECT NON EMPTY [Measures].[%COUNT] ON 0 FROM [Patients]
WHERE %OR({[AgeD].[H1].[Age Bucket].&[80+],[DiagD].[H1].[Diagnoses].&[CHD]})
Patient Count
71