先拋出結論:
1)mysql 可以在 order by 和 group by 中使用別名
2)group by 和 order by 中使用別名時,賦值語句不會重復執行,只是將賦值語句的賦值順序提前觸發了
3)執行順序為 group by -> order by -> select 中的賦值語句
1.1 基礎數據准備
個人 mysql 版本:5.7.19(驗證使用的版本)
公司 mysql 版本:8.x (沒有完全驗證)
Create table If Not Exists Employee (id int, salary int);
Truncate table Employee;
insert into Employee (id, salary) values ('1', '100');
insert into Employee (id, salary) values ('2', '200');
insert into Employee (id, salary) values ('3', '300');
1.2 MySQL 執行順序
這是網上找的 mysql 執行順序,mysql 版本與正確性未知。
from
join
on
where
group by -- 這里開始可以使用 select 中的別名
avg, sum...
having
select
distinct
order by
limit
1.3 Order By 和 Group By 中使用別名
mysql
在 ordery by
和 group by
中使用別名,相當於把別名的語句放在ordery by
和 group by
中。
比如:
select ifnull(salary, '500') as salary_alias
from Employee
order by salary_alias;
等價於
select ifnull(salary, '500')
from Employee
order by ifnull(salary, '500');
於是有了一個問題:既然別名的語句放到了 order by 中,是否語句會被重復執行?
答案是:否。
比如:
set @i = 0;
select @i := @i + 1 as i_alias
from employee
order by @i := @i +1; -- 等價於 order by i_alias
結果為:
1
2
3
確實沒有重復執行。
如果將 order by 的內容改一下,使之與別名的語句不相同,如:
set @i = 0;
select @i := @i + 1 as i
from employee
order by @i := 1 + @i;
結果為:
2
4
6
因為 @i := 1 + @i
不等價於 @i := @i + 1
。
1.4 執行順序驗證
設置兩個變量 @i 和 @s,其中 @i 根據 @s 變化進行賦值,而 @s 在 @i 賦值之后賦值。
即正常的賦值順序為:@i -> @s
set @i = 0;
set @s = '';
select @i := if(@s != salary, @i + 1, @i) as i, @s, @s := salary as s, @s
from employee;
結果為
i @s s @s(1)
1 100 100
2 100 200 200
3 200 300 300
如果加上別名排序
set @i = 0;
set @s = '';
select @i := if(@s != salary, @i + 1, @i) as i, @s, @s := salary as s, @s
from employee
order by s desc;
結果為
i @s s @s(1)
0 300 300 300
1 300 200 200
2 200 100 100
可以看到 @s 的賦值發生在了 @i 之前。
如果加上 group by
set @i = 0;
set @s = '';
select @i := if(@s != salary, @i + 1, @i) as i, @s, @s := salary as s, @s
from employee
group by i, s
order by s desc;
結果為
i @s s @s(1)
3 200 300 300
2 100 200 200
1 100 100
賦值順序又正常了,可以確定:執行順序為先 group by 后 order by。