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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在SQL中的WHERE和HAVING语句中使用别名?相关的知识,希望对你有一定的参考价值。

例:

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

但是,使用HAVING子句可以很好地完成。那么为什么别名在where子句中不起作用?

答案

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

你不能在WHERE(和HAVING)中使用别名的原因是因为SELECT实际上是在大多数其他子条款之后进行评估的:https://stackoverflow.com/a/21693272/159145

从概念上讲,SELECT查询按以下顺序进行评估:

  1. FROM条款
  2. WHERE条款
  3. GROUP BY条款
  4. HAVING条款
  5. SELECT条款
  6. ORDER BY条款

所以你的查询:

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

标准SQL不允许在WHERE子句中引用列别名。强制执行此限制是因为在评估WHERE子句时,可能尚未确定列值。

WHERE子句确定GROUP BY子句中应包含哪些行,但它引用的列别名是在选择行之后才知道的,并按GROUP BY分组。

以上是关于在SQL中的WHERE和HAVING语句中使用别名?的主要内容,如果未能解决你的问题,请参考以下文章

GROUP BY,WHERE,HAVING之间的区别和用法

在oracle中where 子句和having子句中的区别

SQL中的HAVING和WHERE有啥区别?

在oracle中where 子句和having子句中的区别

sql语句中的having

having和where的区别