17.05 - 例: 選択リストに集約が含まれている場合の非集約式上でのGROUP BY句の指定 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQLデータ操作言語

Product
Advanced SQL Engine
Teradata Database
Release Number
17.05
Release Date
2021年1月
Content Type
プログラミング リファレンス
Publication ID
B035-1146-175K-JPN
Language
日本語 (日本)

問合わせで選択式リストに集約を指定した場合は、選択リストからすべての非集約式を含めるGROUP BY句も指定する必要があります。このようにしないと、システムによって次のメッセージが返されます。

     Selected non-aggregate values must be part of the associated group.

システムは、集約問合わせのSELECTリスト内に非集約式があると、エラー メッセージ3504を返します。これは、WHERE句、ORDER BY句、またはHAVING句の場合で、GROUP BY句の場合は返されません。

また、ORDER BY句とWITH句に集約が指定されているとエラーが返されますが、問合わせの選択リストの場合は返されません。

例えば、データベースは次の問合わせをアボートします。この問合わせには、選択リスト内の非集約式だけをグループ化するGROUP BY句であるdepartment_numberを指定しないからです。

     SELECT department_number, SUM(salary_amount)
     FROM employee
     WHERE department_number IN (100, 200, 300);

意図通りに動作させるためには、この問合わせは、次のように適切なGROUP BY句を使用して書き直す必要があります。

     SELECT department_number, SUM(salary_amount)
     FROM employee
     WHERE department_number IN (100, 200, 300)
     GROUP BY department_number;

以下の文は、GROUP BY句内の選択リストから非集約列のすべてを指定しないため、アボートされ、エラーが返されます。

     SELECT employee.dept_no, department.dept_name, AVG(salary)
     FROM employee, department
     WHERE employee.dept_no = department.dept_no
     GROUP BY employee.dept_no;

この場合、修飾非集約列department.dept_nameは、GROUP BY句から欠落しています。

以下の文は、ORDER BY句に指定された非集約のグループ列がGROUP BY句に指定されていないため、アボートされ、エラーが返されます。

     SELECT employee.dept_no, AVG(salary)
     FROM employee, department
     WHERE employee.dept_no = department.dept_no
     ORDER BY department.dept_name
     GROUP BY employee.dept_no;

以下の文は、以下のテーブル定義に基づき、集約問合わせで非集約式d1がHAVING句には含まれているがGROUP BY句には含まれていないため、アボートされ、エラーが返されます。

     CREATE TABLE t1(a1 int, b1 int, c1 int, d1 int);
     CREATE TABLE t2(a2 int, b2 int, c2 int, d2 int);
     SELECT min(a1) as i, max(b1) as j from t1
     GROUP BY c1
     HAVING 30 >= (sel count(*) from t2 where t1.d1=5);

正しい形式の問合わせでは、非集約式d1がHAVING句とGROUP BY句に含まれています。

     SELECT min(a1) as i, max(b1) as j from t1
     GROUP BY c1, d1
     HAVING 30 >= (sel count(*) from t2 where t1.d1=5);