在 WHERE 和 HAVING 语句中使用别名?

Using alias in the WHERE and HAVING statements?

示例:

SELECT customer_id, address_id as addressID 
FROM customer 
WHERE addressID = 5 

但是,使用 HAVING 子句效果很好。那么为什么别名在 where 子句中不起作用?

只有 MySQL 允许在 HAVING 中使用别名,这不是标准的 SQL(参见此处:https://dba.stackexchange.com/questions/50391/why-does-mysql-allow-having-to-use-select-aliases)请注意,没有其他主要的 RDBMS 允许使用WHEREHAVING.

中的别名

你不能在 WHERE(和 HAVING)中使用别名的原因是因为 SELECT 实际上是在大多数其他子句之后计算的:

A SELECT query is evaluated, conceptually, in the following order:

  1. The FROM clause
  2. The WHERE clause
  3. The GROUP BY clause
  4. The HAVING clause
  5. The SELECT clause
  6. The ORDER BY clause

所以你的查询:

SELECT
    customer_id,
    address_id AS addressID 
FROM
    customer 
WHERE
    addressID = 5 

按以下顺序计算:

1: FROM
    customer
2: WHERE
    address_id = 5
3: SELECT
    customer_id,
    address_id AS addressID

如您所见,如果 WHERE 部分引用 addressID 而不是 address_id,查询执行引擎会报错,因为此时未定义 addressID

MySQL 确实允许在 HAVING 中引用(正常)别名,方法是执行一个(非标准)巧妙的技巧,它部分评估 SELECT 之前它评估 HAVING - 因为 MySQL 有别名处理,这意味着评估引擎可以确保别名有效(这就是为什么大多数其他 RDBMS 引擎不这样做的原因允许在 HAVING 中使用别名,否则应该可以)。但是你不能在 WHERE 中使用别名,因为如果有 GROUP BY 那么它可能会使别名变得毫无意义,请考虑:

SELECT
    SUM( foo ) AS baz,
    created
FROM
    foo
WHERE
    baz > 5 -- Meaningless: the GROUP BY hasn't been evaluated yet, so `baz` is unavailable
GROUP BY
    created

MySQL 在他们的手册中对此进行了解释:https://dev.mysql.com/doc/refman/5.7/en/problems-with-alias.html

Standard SQL disallows references to column aliases in a WHERE clause. This restriction is imposed because when the WHERE clause is evaluated, the column value may not yet have been determined.

The WHERE clause determines which rows should be included in the GROUP BY clause, but it refers to the alias of a column value that is not known until after the rows have been selected, and grouped by the GROUP BY.