为了账号安全,请及时绑定邮箱和手机立即绑定

sql里面如何引用列的别名

sql里面如何引用列的别名

慕码人2483693 2019-04-13 08:45:34
描述:selectcolumn1+10asc1,c1+10asc2fromtable1;想实现上面的效果,结果在mysql里面报错了,提示找不到c1这个列;但是selectcolumn1+10asc1wherec1>0fromtable1;这种又是可以的;问题:想知道为什么存在这个问题,还有如果想在表达式中引用列别名,有没有方法可以实现?希望有大牛能贴个详细点的回答出来,介绍下这背后的sql机制,分析下为什么不支持这种方式;这个问题我在stackoverflow有查过,找到的方案也是用子查询跟@申明变量这两种方式;另外个人感觉子查询跟@申明变量这两种方式不够简洁,不知道有没有更好的方案;
查看完整描述

2 回答

?
心有法竹

TA贡献1866条经验 获得超5个赞

mysql中的SQL语句执行是有一定顺序的,如下:
1.from
2.on
3.join
4.where
5.groupby
6.with
7.having
8.select
9.distinct
10.orderby
11.limit
一条SQL会经过这11步的,中间的每一步都会生成一张虚拟表,后面的步骤都是在上一张虚拟表中进行筛选与查询的,下面假设,经过了7步也就是经过了having这一步,生成的虚拟表假设为:
idcolumn1column2alias(having后的别名)
11010aaa
22020bbb
现在到了SELECT这一步的时候,你的查询字段为column1+10asc1,那么sql解析器在这个虚拟表中可以找到column1这个字段,那么计算和设置别名成功,现在你要c1+10,它发现这个虚拟表中不存在这个字段,那么就会报错,如果你想这样做:aliasasxxx,那么也不会报错,因为having筛选过后,这个别名字段已经在虚拟表中了,所以其实道理很简单,select的执行顺序是排在第8步的,而select是针对以上几步生成的虚拟表进行操作的,所以你所要使用的字段,如果虚拟表中不存在,那么则会报错,如果楼主的那句SQL硬要执行的话,也只能改成selectcolumn1+10asc1,column1+10+10asc2fromtable1;
                            
查看完整回答
反对 回复 2019-04-13
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

官方说列表别名可以在GROUPBY,ORDERBY,HAVING中被引用,而标准的SQL禁止在where中被引用,因为where语句有可能执行在先。
官方没有说能否在select语句中引用别名,但根据错误提示可以想到它是先检查所需要的字段名是否存在于被查询的数据中,再进行数据提取。
真正引用别名是做不到了,可以用其它方式,子查询,变量什么的@Foccy的连接中有很多答案
                            
查看完整回答
反对 回复 2019-04-13
  • 2 回答
  • 0 关注
  • 881 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信