Skip to main content

This is documentation for Caché & Ensemble. See the InterSystems IRIS version of this content.Opens in a new tab

For information on migrating to InterSystems IRISOpens in a new tab, see Why Migrate to InterSystems IRIS?

クエリのフィルタ処理

この章では、MDX クエリ内のデータをフィルタ処理する方法を説明します。以下のトピックについて説明します。

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 の患者のスライス) にのみアクセスします。以下はその例です。

generated description: sliced cube

この場合、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} を使用しています。DeepSee はファクト・テーブルにアクセスすると、colord.red に関連付けられたレコードと gend.male に関連付けられたレコードを検索し、それらのレコードをすべて使用します。

Important:

各セット要素は別のスライサ軸として使用され、(すべての %FILTER 節の) すべてのスライサ軸の結果がいっしょに集約されます。これは軸のたたみ込みのプロセスです (フィルタはクエリ軸と見なされます)。軸のたたみ込みを実行すると、どのスライサ軸にも NULL の結果がないソース・レコードは複数回カウントされます。

軸のたたみ込みでは、キューブの定義での指定に従い、対象としているメジャーの集約メソッドに基づいて値が組み合わされます (ここの例では、%COUNT が追加されます)。

詳細は、"DeepSee 実装ガイド" の付録 “DeepSee クエリ・エンジンの仕組み” にある “軸のたたみ込み” を参照してください。

次のセクションでは、さらに別の方法でクエリをフィルタ処理する方法について説明します。

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 最適化

レベルの単一のメンバを除外することが必要な場合も多くあります。これを簡単に行うための方法として、DeepSee の拡張機能である %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

ただし、このクエリ構文では DeepSee がクエリの結果を複数回 (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

前よりも数が減っていることに注意してください。これは、このクエリでは患者を重複してカウントしていないからです。また、このクエリは前のクエリよりも高速です。

リリース 2014.1 以降、異なるレベルのメンバ (またはタプル) を含むセットで %OR を使用できるようになりました。以下はその例です。

SELECT NON EMPTY [Measures].[%COUNT] ON 0 FROM [Patients] 
WHERE %OR({[AgeD].[H1].[Age Bucket].&[80+],[DiagD].[H1].[Diagnoses].&[CHD]})
 
                             Patient Count
                                         71
FeedbackOpens in a new tab