web-dev-qa-db-fra.com

Pouvez-vous utiliser un alias dans la clause WHERE dans mysql?

Je dois utiliser un alias dans la clause WHERE, mais il me répète qu'il s'agit d'une colonne inconnue. Y a-t-il un moyen de contourner ce problème? Je dois sélectionner des enregistrements dont le classement est supérieur à x. La note est calculée comme suit:

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

Vous pouvez utiliser une clause HAVING qui peut voir les alias, par exemple.

 HAVING avg_rating>5

mais dans une clause where, vous devrez répéter votre expression, par exemple.

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

MAIS! Toutes les expressions ne seront pas autorisées. L'utilisation d'une fonction d'agrégation telle que SUM ne fonctionnera pas. Dans ce cas, vous devrez utiliser une clause HAVING.

Depuis le manuel MySQL :

Il n'est pas autorisé de faire référence à un alias de colonne dans une clause WHERE, car il est possible que la valeur de la colonne ne soit pas encore déterminée lors de l'exécution de la clause WHERE. Voir Section B.1.5.4, "Problèmes d’alias de colonnes" .

217
Paul Dixon

Je ne sais pas si cela fonctionne dans mysql, mais en utilisant sqlserver, vous pouvez aussi l'envelopper comme ceci:

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

Cette question est assez ancienne et une réponse a déjà recueilli 160 voix ...

Je voudrais tout de même préciser ceci: la question est en fait et non de savoir si des noms d’alias peuvent être utilisés dans la clause WHERE.

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

est une agrégation. Dans la clause WHERE, nous limitons les enregistrements souhaités à partir des tables en examinant leurs valeurs. sum(reviews.rev_rating) et count(reviews.rev_id) ne sont cependant pas des valeurs que nous trouvons dans un enregistrement; ce sont des valeurs que nous obtenons seulement après avoir agrégé les enregistrements.

Donc, WHERE est inapproprié. Nous avons besoin de HAVING, car nous voulons limiter les résultats après l’agrégation. Ça ne peut pas être

WHERE avg_rating > 10

ni

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

par conséquent.

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

d'autre part est possible et conforme au standard SQL. Tandis que

HAVING avg_rating > 10

n'est possible que dans MySQL. Ce n'est pas un SQL valide selon le standard, car la clause SELECT doit être exécutée après HAVING. De la documentation MySQL:

Une autre extension MySQL au standard SQL autorise les références de la clause HAVING aux expressions avec alias dans la liste de sélection.

L’extension MySQL permet l’utilisation d’un alias dans la clause HAVING pour la colonne agrégée.

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

4
Thorsten Kettner

Si votre requête est statique, vous pouvez la définir en tant que vue, puis vous pouvez utiliser cet alias dans la clause where lors de l'interrogation de la vue.

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