¿Puedes usar un alias en la cláusula WHERE en mysql?

121

Necesito usar un alias en la cláusula WHERE, pero me sigue diciendo que es una columna desconocida. ¿Hay alguna forma de solucionar este problema? Necesito seleccionar registros que tengan una calificación superior a x. La calificación se calcula con el siguiente alias:

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

Respuestas:

229

Podría usar una cláusula HAVING, que puede ver los alias, por ejemplo

 HAVING avg_rating>5

pero en una cláusula where necesitarás repetir tu expresión, por ejemplo

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

¡PERO! No se permitirán todas las expresiones; el uso de una función de agregación como SUM no funcionará, en cuyo caso deberá usar una cláusula HAVING.

Del manual de MySQL :

No se permite hacer referencia a un alias de columna en una cláusula WHERE, porque es posible que el valor de la columna aún no se haya determinado cuando se ejecuta la cláusula WHERE. Consulte la Sección B.1.5.4, “Problemas con los alias de columna” .

Paul Dixon
fuente
1
Si repito la expresión, me dice: "uso no válido de la función de grupo"
3
Se han redactado nuevamente para que sea más claro funciones de agregación no permitidas
Paul Dixon
Buena explicación, esp. la parte "pero en una cláusula where ... repetir ..."
th3an0maly
4
Esta es una buena respuesta, pero tenga en cuenta las implicaciones de rendimiento, ya que se HAVINGejecuta después de que se obtienen los datos y se WHEREejecuta antes.
StockB
No puede usar funciones agregadas en una cláusula WHERE. La cláusula WHERE solo filtra filas de una en una, no grupos completos.
Bill Karwin
33

No sé si esto funciona en mysql, pero usando sqlserver también puede envolverlo como:

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
fuente
6

Esta pregunta es bastante antigua y una respuesta ya obtuvo 160 votos ...

Aún así, dejaría esto en claro: la pregunta en realidad no es si los nombres de alias se pueden usar en la WHEREcláusula.

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

es una agregación. En la WHEREcláusula restringimos los registros que queremos de las tablas mirando sus valores. sum(reviews.rev_rating)ycount(reviews.rev_id) , sin embargo, no son valores que encontremos en un registro; son valores que solo obtenemos después de agregar los registros.

Entonces WHEREes inapropiado. Necesitamos HAVING, ya que queremos restringir las filas de resultados después de la agregación. No puede ser

WHERE avg_rating > 10

ni

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

por lo tanto.

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

por otro lado es posible y cumple con el estándar SQL. Mientras

HAVING avg_rating > 10

solo es posible en MySQL. No es SQL válido de acuerdo con el estándar, ya SELECTque se supone que la cláusula se ejecuta después HAVING. De los documentos de MySQL:

Otra extensión de MySQL para SQL estándar permite referencias en la cláusula HAVING a expresiones con alias en la lista de selección.

La extensión MySQL permite el uso de un alias en la cláusula HAVING para la columna agregada

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

Thorsten Kettner
fuente
0

Si su consulta es estática, puede definirla como una vista, luego puede usar ese alias en la cláusula where mientras consulta la vista.

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