wake-up-neo.com

SQL - Verwenden eines Alias ​​in Group By

Nur neugierig auf SQL-Syntax. Also, wenn ich habe

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY itemName, FirstLetter

Das wäre falsch, weil

GROUP BY itemName, FirstLetter 

sollte es wirklich sein

GROUP BY itemName, substring(itemName, 1,1)

Aber warum können wir die ersteren nicht einfach aus Bequemlichkeitsgründen verwenden?

131
Haoest

SQL wird so implementiert, als ob eine Abfrage in der folgenden Reihenfolge ausgeführt wurde:

  1. FROM-Klausel
  2. WHERE-Klausel
  3. GROUP BY-Klausel
  4. HAVING-Klausel
  5. SELECT-Klausel
  6. ORDER BY-Klausel

In dieser Reihenfolge wird für die meisten relationalen Datenbanksysteme erläutert, welche Namen (Spalten oder Aliase) gültig sind, da sie in einem vorherigen Schritt eingeführt worden sein müssen.

In Oracle und SQL Server können Sie in der GROUP BY-Klausel, die Sie in der SELECT-Klausel definieren, keinen Begriff verwenden, da die GROUP BY-Klausel vor der SELECT-Klausel ausgeführt wird.

Es gibt jedoch Ausnahmen: MySQL und Postgres scheinen eine zusätzliche Intelligenz zu haben, die dies ermöglicht.

255
Codo

Sie können jederzeit eine Unterabfrage verwenden, um den Alias ​​zu verwenden. Überprüfen Sie natürlich die Leistung (Möglicherweise läuft der Datenbankserver auf beiden Servern gleich, es tut jedoch nie weh, dies zu überprüfen):

SELECT ItemName, FirstLetter, COUNT(ItemName)
FROM (
    SELECT ItemName, SUBSTRING(ItemName, 1, 1) AS FirstLetter
    FROM table1
    ) ItemNames
GROUP BY ItemName, FirstLetter
25
Chris Shaffer

Zumindest in PostgreSQL können Sie die Spaltennummer in der Ergebnismenge in Ihrer GROUP BY-Klausel verwenden:

SELECT 
 itemName as ItemName,
 substring(itemName, 1,1) as FirstLetter,
 Count(itemName)
FROM table1
GROUP BY 1, 2

Wenn Sie dies interaktiv tun und die Abfrage bearbeiten, um die Anzahl oder Reihenfolge der Spalten im Ergebnis zu ändern, wird dies natürlich zu einer Belastung. Aber dennoch.

15
Bill Gribble

In SQL Server können Sie aufgrund der logischen Verarbeitungsreihenfolge nicht auf den Alias ​​in der GROUP BY-Klausel verweisen. Die GROUP BY-Klausel wird vor der SELECT-Klausel verarbeitet, sodass der Alias ​​nicht bekannt ist, wenn die GROUP BY-Klausel ausgewertet wird. Dies erklärt auch, warum Sie den Alias ​​in der ORDER BY-Klausel verwenden können.

Hier ist eine Quelle für Informationen zu logische Verarbeitungsphasen von SQL Server .

12
bobs

Ich antworte nicht, warum es so ist, sondern wollte nur zeigen, wie man diese Einschränkung in SQL Server umgeht, indem man den Alias ​​mit CROSS APPLY Erstellt. Sie verwenden es dann in der GROUP BY - Klausel wie folgt:

SELECT 
 itemName as ItemName,
 FirstLetter,
 Count(itemName)
FROM table1
CROSS APPLY (SELECT substring(itemName, 1,1) as FirstLetter) Alias
GROUP BY itemName, FirstLetter
5
Ricardo

Beachten Sie, dass die Verwendung von Aliasnamen in Group By (für Dienste, die dies unterstützen, z. B. Postgres) zu unbeabsichtigten Ergebnissen führen kann. Wenn Sie beispielsweise einen Alias ​​erstellen, der bereits in der inneren Anweisung vorhanden ist, wählt Group By den Namen des inneren Felds aus.

-- Working example in postgres
select col1 as col1_1, avg(col3) as col2_1
from
    (select gender as col1, maritalstatus as col2, 
    yearlyincome as col3 from customer) as layer_1
group by col1_1;

-- Failing example in postgres
select col2 as col1, avg(col3)
from
    (select gender as col1, maritalstatus as col2,
    yearlyincome as col3 from customer) as layer_1
group by col1;
4
Shannon S

In einigen DBMS können Sie einen Alias ​​verwenden, anstatt den gesamten Ausdruck wiederholen zu müssen.
Teradata ist ein solches Beispiel.

Ich vermeide die von Bill empfohlene Schreibweise der Ordinalposition aus Gründen, die in this SO question .

Die einfache und robuste Alternative besteht darin, den Ausdruck in der GROUP BY-Klausel immer zu wiederholen.
DRY gilt NICHT für SQL.

3
bernie

Verwenden Sie keine Aliase, wenn Sie die Ergebnisse aus einer Ansicht in SQLite gruppieren. Sie erhalten unerwartete Ergebnisse, wenn der Aliasname mit dem Spaltennamen der zugrunde liegenden Tabellen (für die Ansichten) übereinstimmt.

1
GGGforce

Damals stellte ich fest, dass Rdb, das frühere DEC-Produkt, das jetzt von Oracle unterstützt wird, die Verwendung des Spaltenalias in GROUP BY ermöglichte. In Mainstream Oracle bis Version 11 kann der Spaltenalias nicht in GROUP BY verwendet werden. Nicht sicher, was Postgresql, SQL Server, MySQL usw. zulässt oder nicht. YMMV.

0
Bob Jarvis