Puoi usare un alias nella clausola WHERE in mysql?


121

Devo usare un alias nella clausola WHERE, ma continua a dirmi che è una colonna sconosciuta. C'è un modo per aggirare questo problema? Devo selezionare record con una valutazione superiore a x. La valutazione viene calcolata come il seguente alias:

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

Risposte:


229

Potresti usare una clausola HAVING, che può vedere gli alias, ad es

 HAVING avg_rating>5

ma in una clausola where dovrai ripetere la tua espressione, ad es

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

MA! Non tutte le espressioni saranno consentite: l'utilizzo di una funzione di aggregazione come SUM non funzionerà, nel qual caso sarà necessario utilizzare una clausola HAVING.

Dal manuale MySQL :

Non è consentito fare riferimento a un alias di colonna in una clausola WHERE, poiché il valore della colonna potrebbe non essere ancora determinato quando viene eseguita la clausola WHERE. Vedere la Sezione B.1.5.4, "Problemi con gli alias di colonna" .


1
Se ripeto l'espressione, mi dice: "uso non valido della funzione di gruppo"

3
Ho riformulato per rendere più chiaro le funzioni di aggregazione non consentite
Paul Dixon

Bella spiegazione, specialmente la parte "ma in una clausola dove ... ripeti .."
th3an0maly

4
Questa è una buona risposta, ma considera le implicazioni sulle prestazioni poiché HAVINGviene eseguito dopo che i dati sono stati recuperati ed WHEREeseguito prima.
StockB

Non è possibile utilizzare funzioni aggregate in una clausola WHERE. La clausola WHERE filtra solo le righe una alla volta, non interi gruppi.
Bill Karwin il

33

Non so se funziona in mysql ma usando sqlserver puoi anche avvolgerlo come:

select * from (
  -- your original query
  select .. sum(reviews.rev_rating)/count(reviews.rev_id) as avg_rating 
  from ...) Foo
where Foo.avg_rating ...

6

Questa domanda è piuttosto vecchia e una risposta ha già ottenuto 160 voti ...

Tuttavia vorrei chiarire questo punto: la domanda in realtà non è se i nomi alias possano essere usati nella WHEREclausola.

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

è un'aggregazione. Nella WHEREclausola restringiamo i record desiderati dalle tabelle osservando i loro valori. sum(reviews.rev_rating)e count(reviews.rev_id), tuttavia, non sono valori che troviamo in un record; sono valori che otteniamo solo dopo aver aggregato i record.

Quindi WHEREè inappropriato. Abbiamo bisogno HAVING, poiché vogliamo limitare le righe dei risultati dopo l'aggregazione. Non può essere

WHERE avg_rating > 10

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

quindi.

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

d'altra parte è possibile ed è conforme allo standard SQL. Mentre

HAVING avg_rating > 10

è possibile solo in MySQL. Non è SQL valido secondo lo standard, poiché la SELECTclausola dovrebbe essere eseguita dopo HAVING. Dai documenti MySQL:

Un'altra estensione di MySQL allo standard SQL consente i riferimenti nella clausola HAVING alle espressioni con alias nell'elenco di selezione.

L'estensione MySQL consente l'uso di un alias nella clausola HAVING per la colonna aggregata

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


0

Se la tua query è statica, puoi definirla come una vista, quindi puoi usare quell'alias nella clausola where durante l'interrogazione della vista.


0
SELECT * FROM (SELECT customer_Id AS 'custId', gender, age FROM customer
    WHERE  gender = 'F') AS c
WHERE c.custId = 100;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.