ホームページ  >  に質問  >  本文

mysql - sql里面如何引用列的别名

描述:
select column1+10 as c1,c1+10 as c2 from table1;
想实现上面的效果,结果在mysql里面报错了,提示找不到c1这个列;
但是select column1+10 as c1 where c1>0 from table1;这种又是可以的;

问题:
想知道为什么存在这个问题,还有如果想在表达式中引用列别名,有没有方法可以实现?


希望有大牛能贴个详细点的回答出来,介绍下这背后的sql机制,分析下为什么不支持这种方式;
这个问题我在stackoverflow有查过,找到的方案也是用子查询跟@申明变量这两种方式;
另外个人感觉子查询跟@申明变量这两种方式不够简洁,不知道有没有更好的方案;

怪我咯怪我咯2742日前656

全員に返信(4)返信します

  • PHP中文网

    PHP中文网2017-04-17 11:36:30

    mysql中的SQL语句执行是有一定顺序的,如下:
    1. from
    2. on
    3. join
    4. where
    5. group by
    6. with
    7. having
    8. select
    9. distinct
    10. order by
    11. limit
    一条SQL会经过这11步的,中间的每一步都会生成一张虚拟表,后面的步骤都是在上一张虚拟表中进行筛选与查询的,下面假设,经过了7步也就是经过了having这一步,生成的虚拟表假设为:

    id  column1 column2 alias(having后的别名)
    1      10       10      aaa
    2      20       20      bbb
    

    现在到了SELECT这一步的时候,你的查询字段为 column1+10 as c1, 那么sql解析器在这个虚拟表中可以找到column1这个字段,那么计算和设置别名成功, 现在你要c1+10,它发现这个虚拟表中不存在这个字段,那么就会报错,如果你想这样做:alias as xxx, 那么也不会报错,因为having筛选过后,这个别名字段已经在虚拟表中了,所以其实道理很简单,select的执行顺序是排在第8步的,而select是针对以上几步生成的虚拟表进行操作的,所以你所要使用的字段,如果虚拟表中不存在,那么则会报错,如果楼主的那句SQL硬要执行的话,也只能改成select column1+10 as c1,column1+10+10 as c2 from table1;

    返事
    0
  • 怪我咯

    怪我咯2017-04-17 11:36:30

    官方说列表别名可以在 GROUP BY, ORDER BY, HAVING中被引用,而标准的SQL禁止在where中被引用,因为where语句有可能执行在先。

    官方没有说能否在select 语句中引用别名,但根据错误提示可以想到它是先检查所需要的字段名是否存在于被查询的数据中,再进行数据提取。

    真正引用别名是做不到了,可以用其它方式,子查询,变量什么的 @Foccy 的连接中有很多答案

    返事
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:36:30

    多用google. http://stackoverflow.com/questions/6081436/how-to-use-alias-as-field-in-mysql

    返事
    0
  • 巴扎黑

    巴扎黑2017-04-17 11:36:30

    stackoverflow上有个帖子介绍了在同一条查询中引用变量可能存在的问题:
    http://stackoverflow.com/questions/16715504/mysql-define-a-variable-within-select-and-use-it-within-the-same-select/16715618#16715618
    提这个问题主要是因为有的sql语句中表达式计算很复杂,而后面又希望引用这个计算结果来计算得到另外一列,这种情况是不是要定义个存储过程来处理比较好?

    返事
    0
  • キャンセル返事