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

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” .


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 ...

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


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.


0
SELECT * FROM (SELECT customer_Id AS 'custId', gender, age FROM customer
    WHERE  gender = 'F') AS c
WHERE c.custId = 100;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.