搜尋

首頁  >  問答  >  主體

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有查过,找到的方案也是用子查询跟@申明变量这两种方式;
另外个人感觉子查询跟@申明变量这两种方式不够简洁,不知道有没有更好的方案;

怪我咯怪我咯2874 天前710

全部回覆(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
  • 取消回覆