Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 12.0.1 » SQL Anywhere サーバー SQL の使用法 » データの問い合わせと修正 » クエリ結果の要約、グループ化、ソート » GROUP BY 句:クエリ結果のグループへの編成

 

GROUP BY と SQL/2008 標準

SQL/2008 標準の構文には、SQL Anywhere でサポートされている構文よりもかなり多くの制約があります。GROUP BY について、SQL/2008 標準では次のように定めています。

  • GROUP BY 句で指定された各 group-by-term は、カラム参照である必要があります。つまり、テーブルからカラムへの参照は、クエリ FROM 句で参照されます。これらの式は、「グループ化カラム」と呼ばれます。

  • SELECT リスト、HAVING 句、または ORDER BY 句内の集合関数でない式は、グループ化カラムであるか、グループ化カラムだけを参照する必要があります。ただし、オプションの SQL/2008 言語機能 T301 "Functional dependencies" がサポートされている場合、このような参照では、グループ化カラムによって機能的に決定されたクエリ FROM 句からカラムを参照できます。

SQL Anywhere の GROUP BY 句では、group-by-term を、列参照、リテラル定数、変数またはホスト変数、スカラー関数、ユーザー定義関数を含む任意の式にできます。たとえば、次のクエリでは、Employee テーブルは Salary カラムに基づいて 3 つのグループに分割され、グループあたり 1 つのローが生成されます。

SELECT COUNT() FROM Employees 
   GROUP BY (
      IF SALARY < 25000 
         THEN 'low range' 
      ELSE IF Salary < 50000 
         THEN 'mid range' 
      ELSE 'high range' 
         ENDIF 
      ENDIF);

クエリ結果に分割値を含めるには、クエリ SELECT リストに group-by-term を追加する必要があります。構文的に有効であるために、SQL Anywhere では、SELECT リスト項目の構文と group-by-term の構文が同じであることが確認されます。ただし、構文的に大きい SQL 構成では、この分析は失敗することがあります。さらに、サブクエリを含む式では等しいことの比較は行われません。

次の例では、SQL Anywhere は 2 つの IF 式が同じであることを検出し、エラーなしに結果を計算します。

SELECT (IF SALARY < 25000 THEN 'low range' ELSE IF Salary < 50000 THEN 'mid range' ELSE 'high range' ENDIF ENDIF), COUNT() 
FROM Employees 
GROUP BY (IF SALARY < 25000 THEN 'low range' ELSE IF Salary < 50000 THEN 'mid range' ELSE 'high range' ENDIF ENDIF);

ただし、次のクエリには、エラーを返すサブクエリが GROUP BY 句に含まれています。

SELECT (Select State from Employees e WHERE e.EmployeeID = e2.EmployeeID), 
      COUNT() 
   FROM Employees e2
   GROUP BY (Select State from Employees e WHERE EmployeeID = e2.EmployeeID)

より簡潔な方法は、SELECT リスト式でエイリアスを使用し、GROUP BY 句内でエイリアスを参照することです。エイリアスを使用すると、SELECT リストと GROUP BY 句に相関サブクエリを含めることができます。次のような形で使用される SELECT リストエイリアスは、ベンダー拡張です。



SELECT (
   IF SALARY < 25000 
      THEN 'low range' 
   ELSE IF Salary < 50000 
      THEN 'mid range' 
   ELSE 'high range' 
      ENDIF
   ENDIF) AS Salary_Range, 
   COUNT() FROM Employees GROUP BY Salary_Range;

SQL Anywhere は、SQL/2008 言語機能 T301 (Functional dependencies) のすべての部分をサポートしているわけではありませんが、GROUP BY の単語に基づいて派生値をサポートしています。SQL Anywhere は、GROUP BY の単語、リテラル定数、(ホスト) 変数を参照する SELECT リスト式を、それらの値を変更する可能性があるスカラー関数の有無に関係なくサポートしています。例として、次のクエリでは、市と州の組み合わせ別に従業員の数がリストされます。

SELECT City || ' ' || State, SUBSTRING(City,1,3), COUNT() 
FROM Employees 
GROUP BY City, State
 参照