Der SQL/2008-Standard ist in seiner Syntax erheblich restriktiver als der von SQL Anywhere unterstützte. Im SQL/2008-Standard erfordert GROUP BY folgende Bedingungen:
Jedes in einer GROUP BY-Klausel angegebenes Gruppieren_nach_Begriff muss eine Spaltenreferenz sein, d.h. eine Referenz auf eine Spalte aus einer Tabelle, die in der FROM-Klausel der Abfrage referenziert wird. Diese Ausdrücke werden gruppierten Spalten genannt.
Ein Ausdruck in einer SELECT-Liste, HAVING-Klausel oder ORDER BY-Klausel, der keine Aggregatfunktion ist, muss eine gruppierte Spalte sein oder darf nur gruppierte Spalten referenzieren. Wenn jedoch die optionale SQL/2008-Sprachfunktion T301, "Funktionale Abhängigkeiten", unterstützt wird, kann so eine Referenz Spalten aus der FROM-Klausel der Abfrage referenzieren, die funktionell durch gruppierte Spalten festgelegt werden.
In einer GROUP BY-Klausel in SQL Anywhere kann Gruppieren_nach_Begriff ein beliebiger Ausdruck sein, der Spaltenreferenzen, literale Konstanten, Variablen oder Hostvariablen sowie skalare und benutzerdefinierte Funktionen betrifft. Diese Abfrage beispielsweise partitioniert die Tabelle "Employee" in drei Gruppen basierend auf die Spalte "Salary" und erzeugt eine Zeile pro Gruppe:
SELECT COUNT() FROM Employees GROUP BY ( IF SALARY < 25000 THEN 'low range' ELSE IF Salary < 50000 THEN 'mid range' ELSE 'high range' ENDIF ENDIF); |
Um den Partitionswert in das Abfrageergebnis aufzunehmen, müssen Sie ein Gruppieren_nach_Begriff der SELECT-Liste der Abfrage hinzufügen. Um syntaktisch gültig zu sein, stellt SQL Anywhere sicher, dass die Syntax des SELECT-Listenelements und von Gruppieren_nach_Begriff identisch sind. Allerdings scheitern möglicherweise syntaktisch umfassende SQL-Konstruktionen bei dieser Analyse; auch werden Ausdrücke, die Unterabfragen betreffen, nie als gleichwertig verglichen.
Im unten stehenden Beispiel erkennt SQL Anywhere, dass die zwei IF-Ausdrücke identisch sind, und ermittelt das Ergebnis ohne Fehler:
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); |
Jedoch enthält diese Abfrage eine Unterabfrage in der GROUP BY-Klausel und gibt einen Fehler zurück:
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) |
Eine besserer Ansatz ist es, dem SELECT-Listenausdruck einen Alias zuzuweisen und diesen in der GROUP BY-Klausel zu referenzieren. Die Verwendung eines Alias ermöglicht es der SELECT-Liste und der GROUP BY-Klausel, korrelierte Unterabfragen zu enthalten. Bei auf diese Weise verwendeten SELECT-Listen-Aliasnamen handelt es sich um eine Erweiterung des Herstellers:
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; |
Auch wenn SQL Anywhere nicht alle Facetten der SQL/2008-Sprachfunktion T301 (Funktionale Abhängigkeiten) unterstützt, so bietet SQL Anywhere doch etwas Unterstützung für abgeleitete Werte, die auf GROUP BY-Begriffen basieren. SQL Anywhere unterstützt SELECT-Listenausdrücke, die GROUP BY-Begriffe, literale Konstanten und (Host-)Variablen mit oder ohne Skalarfunktionen referenzieren, die diese Werte ändern können. Die folgende Abfrage beispielsweise listet die Anzahl von Mitarbeitern anhand der City-/State-Kombination auf:
SELECT City || ' ' || State, SUBSTRING(City,1,3), COUNT() FROM Employees GROUP BY City, State |
![]() |
Kommentieren Sie diese Seite in DocCommentXchange.
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |