Você pode usar um alias na cláusula WHERE no mysql?

121

Eu preciso usar um alias na cláusula WHERE, mas continua me dizendo que é uma coluna desconhecida. Existe alguma maneira de contornar esse problema? Preciso selecionar registros com uma classificação maior que x. A classificação é calculada como o seguinte alias:

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

Respostas:

229

Você pode usar uma cláusula HAVING, que pode ver os aliases, por exemplo

 HAVING avg_rating>5

mas em uma cláusula where você precisará repetir sua expressão, por exemplo

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

MAS! Nem todas as expressões serão permitidas - o uso de uma função agregadora como SUM não funcionará; nesse caso, você precisará usar uma cláusula HAVING.

No Manual do MySQL :

Não é permitido fazer referência a um alias de coluna em uma cláusula WHERE, porque o valor da coluna ainda não pode ser determinado quando a cláusula WHERE for executada. Consulte a Seção B.1.5.4, “Problemas com aliases de coluna” .

Paul Dixon
fonte
1
Se eu repetir a expressão, ela diz: "uso inválido da função de grupo"
3
Ter reformulado para torná-lo funções aggregrating mais claras não allowedd
Paul Dixon
Boa explicação, esp. o "mas em uma cláusula onde ... repeat .." parte
th3an0maly
4
Essa é uma boa resposta, mas considere as implicações de desempenho, pois é HAVINGexecutado depois que os dados são buscados e WHEREantes.
StockB
Você não pode usar funções agregadas em uma cláusula WHERE. A cláusula WHERE filtra apenas as linhas uma por vez, não grupos inteiros.
Bill Karwin
33

Não sei se isso funciona no mysql, mas usando o sqlserver, você também pode envolvê-lo 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
fonte
6

Esta pergunta é bastante antiga e uma resposta já obteve 160 votos ...

Ainda assim, eu deixaria isso claro: na verdade, a questão não é se nomes de alias podem ser usados ​​na WHEREcláusula.

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

é uma agregação. Na WHEREcláusula, restringimos os registros que queremos das tabelas observando seus valores. sum(reviews.rev_rating)e count(reviews.rev_id), no entanto, não são valores que encontramos em um registro; são valores que só obtemos após agregar os registros.

Então WHEREé inapropriado. Precisamos HAVING, pois queremos restringir as linhas de resultados após a agregação. Não pode ser

WHERE avg_rating > 10

nem

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

conseqüentemente.

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

por outro lado, é possível e está em conformidade com o padrão SQL. Enquanto que

HAVING avg_rating > 10

só é possível no MySQL. Não é um SQL válido de acordo com o padrão, pois a SELECTcláusula deve ser executada depois HAVING. Nos documentos do MySQL:

Outra extensão do MySQL para o SQL padrão permite referências na cláusula HAVING a expressões com alias na lista de seleção.

A extensão MySQL permite o uso de um alias na cláusula HAVING para a coluna agregada

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

Thorsten Kettner
fonte
0

Se sua consulta for estática, você poderá defini-la como uma visualização, e poderá usar esse alias na cláusula where enquanto estiver consultando a visualização.

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