GROUP BY句

GROUP BY句はSELECT文で使用して、複数行にわたるデータを収集し、結果を1つ以上の列または式でグループ化します。GROUP BY句は、多くの場合、集計関数とともに使用します。Oracle NoSQL Databaseでは、集計関数が行の各グループに適用され、グループごとに1行が返されます。

構文

groupby_clause ::= GROUP BY expression ("," expression)*

セマンティクス

各(グループ化)式は、最大で1つのアトミック値を返す必要があります。グループ化式が入力行に対して空の結果を返す場合、その行はスキップされます。グループ化値間の等価性は、=演算子のセマンティクスに従って定義されます。ただし、2つのNULL値は等しいとみなされます。値の比較演算子の項を参照してください。次に、グループごとに、GROUP BY句によって単一のレコードが作成されて返されます。この句にN個のグループ化式がある場合は、返されたレコードの最初のN個のフィールドに、グループ化式の値が格納されます。残りのM個のフィールド(m >= 0)には、ゼロ個以上の集計関数の結果が格納されます。一般に集計関数は、グループの行を反復し、該当する各行の式を評価し、返された値をグループごとに1つの値に集計します。Oracle NoSQL Databaseでは、集計関数の使用の項で説明されているような多くの集計関数がサポートされます。

構文的には、集計関数は実際にはGROUP BY句にリストされませんが、SELECT句には表示されます。実際、集計関数はSELECT句にのみ表示され、ネストすることはできません。ただし、意味的にはSELECTリストに表示される各集計関数は、実際にはGROUP BY句によって評価されます。SELECT句に集計関数が含まれていても、SELECT式にGROUP BY句が含まれていない場合は、FROM句またはWHERE句で生成されたすべての行が1つのグループとみなされ、集計関数がこの1つのグループ全体に対して評価されます。

前述のルールは、GROUP BY句の一般的なセマンティクスについて説明しています。ただし、現行の実装では、グループ化を実際に実行できる場合に、重要な制限が課されます。具体的には、グループ化式の値によって行をすでにソートしているコンパイル時に非複数キー索引(配列またはマップの値に索引付けしない索引。単純索引の項を参照)がある場合にのみ、グループ化は可能です。より正確には、e1, e2, …, eNをGROUP BY句(左から右)に表示されるグループ化式にできます。次に、1,2,...,N, eiの各iがi番目の索引フィールドの定義に一致する索引(主キー索引または既存の2次索引の1つである可能性があります)が存在する必要があります。コンパイル時には、索引が非複数キーである必要があるため、問合せの実行中にグループ化式によってアトミック項目が2つ以上返されることはありません。

ORDER BY句に類似の制限が存在します。その結果、現在、同じSELECT式にGROUP BYとORDER BYの両方を含めることはできません。一方、グループ化は索引の順序付けに基づいて実装されるため、グループ化SELECTの結果はグループ化式に基づいて順序付けられます。

例6-4 GROUP BY句

SELECT 
age, 
count(*) AS count, 
avg(income) AS income 
FROM users 
GROUP BY age;

この問合せは、ユーザーを年齢別にグループ化し、グループごとに、そのグループのユーザーの年齢と平均収入を返します。グループ化は、年齢列に2次索引(または、通常は、最初の列が年齢列である複数列索引)がある場合にのみ可能です。