GROUP句/GROUP BY句

GROUP句およびGROUP BY句では、文の出力をグルーピングするためにソース・レコードをどのように結果レコードにマッピングするかを指定します。

これらの句を問合せで使用するには、次のような方法があります。

その他のグルーピング関数(たとえば、MEMBERSCUBEGROUPING SETSなど)も、GROUP句やGROUP BY句とともに使用できます。このような関数の詳細は、この項で後述します。

グルーピングのためのBNF文法

BNF文法によるGROUPおよびグルーピング関数ファミリの表記は次のとおりです。
GroupClause ::= GROUP | GROUP BY GroupByList | GROUP BY GroupAll
GroupByList ::= GroupByElement | GroupByList ,  GroupByElement
GroupByElement ::= GroupBySingle | GroupingSets | CubeRollup

GroupingSets ::= GROUPING SETS (GroupingSetList)
GroupingSetList ::=  GroupingSetElement |  GroupingSetList ,  GroupingSetElement
GroupingSetElement ::=  GroupBySingle | GroupByComposite | CubeRollup | GroupAll

CubeRollup ::= {CUBE | ROLLUP} (CubeRollupList)
CubeRollupList ::=  CubeRollupElement |  CubeRollupList ,  CubeRollupElement
CubeRollupElement ::=  GroupBySingle | GroupByComposite

GroupBySingle ::= Identifier | GroupByMembers
GroupByComposite ::= (GroupByCompositeList)
GroupByCompositeList ::= GroupBySingle | GroupByCompositeList, GroupBySingle
GroupByMembers ::= MEMBERS (Identifier | Identifier.Identifier) AS Indentifier

GroupAll ::= ()
GroupAllを使用すると、次に示すものがすべて等価になることに注意してください。
GROUP = GROUP BY() = GROUP BY GROUPING SETS(())

GROUPのみを指定

GROUP句を使用すると、結果を集計して1つのバケットを作成できます。BNF文法が示すように、GROUP句は引数を取りません。

たとえば、次に示す文ではSUM文を使用してレコードのセット全体の合計を1つのみ返します。
RETURN ReviewCount AS 
SELECT SUM(NumReviews) AS NumberOfReviews
GROUP

この文が返すのは、NumberOfReviewsのレコード1つです。値は、NumReviews属性の値の合計です。

GROUP BYの指定

GROUP BYを使用すると、グルーピング・キーの値が同じである結果を集計してバケットを作成できます。GROUP BYの構文は次のとおりです。
GROUP BY attributeList
attributeListは、単一の属性、カンマ区切りの複数属性リスト、GROUPING SETSCUBEまたはROLLUPです。()を指定すると、空のグループを指定したことになります。空のグループを指定すると、合計が生成されます。

グルーピングは、ソースおよびローカルで定義された属性に対して実行できます。

注意: ローカル定義された属性でグルーピングする場合は、その属性は非グルーピング属性を参照することはできず、その属性に集計を含めることはできません。ただし、IN式とルックアップ式は、このコンテキストでは有効です。

グルーピング属性はすべて、結果レコードに含まれます。いずれのグルーピング属性においても、NULL値(単一割当て属性用)または空のセット(複数割当て用)は、他の値と同様に扱われます。これは、ソース・レコードが結果レコードにマップされることを意味します。ただし、NULL値および空のセットをコーパスから選択した場合は無視されます(指定した状態や、AllBaseRecordsまたはNavStateRecordsから選択した場合も含みます)。EQLでのユーザー定義のNULL値の扱いの詳細は、COALESCEを参照してください。

たとえば、販売トランザクション・データのレコードが、次の属性で構成されているとします。
{ TransId, ProductType, Amount, Year, Quarter, Region,
  SalesRep, Customer }
次に例を示します。
{ TransId = 1, ProductType = "Widget", Amount = 100.00,
  Year = 2011, Quarter = "11Q1", Region  = "East",
  SalesRep = "J. Smith", Customer = "Customer1" }
EQL文でRegionとYearをGROUP BYの属性として使用する場合は、文の結果には、有効で、空ではないRegionとYearの各組合せからなる、集計レコードが出力されます。EQLでは、この例は次のように表現されます。
DEFINE RegionsByYear AS
GROUP BY Region, Year
この結果は、{ Region, Year }という形式の集計です。次に例を示します。
{ "East", "2010" }
{ "West", "2011" }
{ "East", "2011" }
GROUP BY句の中では、同じ列を重複して使用できることに注意してください。つまり、次の2つの問合せは、等価として扱われます。
RETURN Results AS
SELECT SUM(PROMO_COST) AS PR_Cost
GROUP BY PROMO_NAME

RETURN Results AS
SELECT SUM(PROMO_COST) AS PR_Cost
GROUP BY PROMO_NAME, PROMO_NAME

SELECT式の出力であるGROUP BYの使用

GROUP BYのキーは、SELECT式の出力であってもかまいません。ただし、その式自体に集計関数が含まれていないことが条件です。

たとえば、次に示す構文はGROUP BYの正しい使用法です。
SELECT COALESCE(Person, 'Unknown Person') AS Person2, ... GROUP BY Person2
次に示す構文は間違っているため、結果はエラーになります。Sales2の中に集計関数(SUM)があるからです。
SELECT SUM(Sales) AS Sales2, ... GROUP BY Sales2

管理対象属性の階層レベルの指定

各管理対象属性の指定した深さでグルーピングできます。ただし、GROUP BY文ではANCESTOR関数は使用できません(EQLでは式のグルーピングができないからです)。したがって、最初にANCESTORSELECT文とともに使用してから、別名を付けた結果をGROUP BY句の中で指定します。

たとえば、Region属性の中にCountry、State、Cityの階層があるとします。結果のグルーピングを、Stateレベル(管理対象属性階層のルートの1レベル下)で行うとします。省略形の問合せを次に示します。
SELECT ANCESTOR("Region", 1) AS StateInfo
...
GROUP BY StateInfo