Können Sie einen Alias ​​in der WHERE-Klausel in MySQL verwenden?

121

Ich muss einen Alias ​​in der WHERE-Klausel verwenden, aber es sagt mir immer wieder, dass es sich um eine unbekannte Spalte handelt. Gibt es eine Möglichkeit, dieses Problem zu umgehen? Ich muss Datensätze auswählen, deren Bewertung höher als x ist. Die Bewertung wird als folgender Alias ​​berechnet:

sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating
dreftymac
quelle

Antworten:

229

Sie können eine HAVING-Klausel verwenden, die die Aliase anzeigen kann , z

 HAVING avg_rating>5

In einer where-Klausel müssen Sie jedoch Ihren Ausdruck wiederholen, z

 WHERE (sum(reviews.rev_rating)/count(reviews.rev_id))>5

ABER! Nicht alle Ausdrücke sind zulässig. Die Verwendung einer Aggregationsfunktion wie SUM funktioniert nicht. In diesem Fall müssen Sie eine HAVING-Klausel verwenden.

Aus dem MySQL-Handbuch :

Es ist nicht zulässig, in einer WHERE-Klausel auf einen Spaltenalias zu verweisen, da der Spaltenwert bei der Ausführung der WHERE-Klausel möglicherweise noch nicht ermittelt wurde. Siehe Abschnitt B.1.5.4, „Probleme mit Spaltenaliasen“ .

Paul Dixon
quelle
1
Wenn ich den Ausdruck wiederhole, sagt er mir: "Ungültige Verwendung der Gruppenfunktion"
3
Habe umformuliert, um es klarer zu machen. Aggregrating-Funktionen nicht erlaubt
Paul Dixon
Schöne Erklärung, insb. der Teil "aber in einer where-Klausel ... wiederholen ..."
th3an0maly
4
Dies ist eine gute Antwort, aber bitte berücksichtigen Sie die Auswirkungen auf die Leistung, da sie HAVINGausgeführt wird, nachdem die Daten abgerufen wurden und WHEREzuvor ausgeführt wurden.
StockB
Sie können keine Aggregatfunktionen in einer WHERE-Klausel verwenden. Die WHERE-Klausel filtert nur Zeilen nacheinander, nicht ganze Gruppen.
Bill Karwin
33

Keine Ahnung, ob dies in MySQL funktioniert, aber mit SQL Server können Sie es auch wie folgt umbrechen:

select * from (
  -- your original query
  select .. sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating 
  from ...) Foo
where Foo.avg_rating ...
Torbjörn Gyllebring
quelle
6

Diese Frage ist ziemlich alt und eine Antwort hat bereits 160 Stimmen erhalten ...

Dennoch würde ich dies klarstellen: Die Frage ist eigentlich nicht, ob Aliasnamen in der WHEREKlausel verwendet werden können.

sum(reviews.rev_rating) / count(reviews.rev_id) as avg_rating

ist eine Aggregation. In der WHEREKlausel beschränken wir die gewünschten Datensätze aus den Tabellen, indem wir ihre Werte betrachten. sum(reviews.rev_rating)undcount(reviews.rev_id) sind jedoch keine Werte, die wir in einem Datensatz finden; Dies sind Werte, die wir erst nach der Aggregation der Datensätze erhalten.

Ist WHEREalso unangemessen. Wir brauchen HAVING, da wir Ergebniszeilen nach der Aggregation einschränken wollen. Es kann nicht sein

WHERE avg_rating > 10

Noch

WHERE sum(reviews.rev_rating) / count(reviews.rev_id) > 10

daher.

HAVING sum(reviews.rev_rating) / count(reviews.rev_id) > 10

Zum anderen ist dies möglich und entspricht dem SQL-Standard. Wohingegen

HAVING avg_rating > 10

ist nur in MySQL möglich. Es ist kein gültiges SQL gemäß dem Standard, da die SELECTKlausel danach ausgeführt werden soll HAVING. Aus den MySQL-Dokumenten:

Eine andere MySQL-Erweiterung für Standard-SQL ermöglicht Verweise in der HAVING-Klausel auf Alias-Ausdrücke in der Auswahlliste.

Die MySQL-Erweiterung ermöglicht die Verwendung eines Alias ​​in der HAVING-Klausel für die aggregierte Spalte

https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

Thorsten Kettner
quelle
0

Wenn Ihre Abfrage statisch ist, können Sie sie als Ansicht definieren und diesen Alias ​​in der where-Klausel verwenden, während Sie die Ansicht abfragen.

alpere
quelle
0
SELECT * FROM (SELECT customer_Id AS 'custId', gender, age FROM customer
    WHERE  gender = 'F') AS c
WHERE c.custId = 100;
Anson
quelle