Mysql用戶變量的形式是:@var,其可以使用的場合很多,例如新增一列排序值、分組排序等。
下面讓我們來探討一下其部分應用場景。
1. 首先建表,插入數據:
create table t_variable ( name_people VARCHAR(255) NOT NULL comment '姓名', grade VARCHAR(255) NOT NULL comment '年級', course VARCHAR(255) NOT NULL comment '科目', score VARCHAR(255) NOT NULL comment '分數' )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='test_變量'; insert into t_variable(name_people, grade, course, score) values('花滿樓',5,'數學',86); insert into t_variable(name_people, grade, course, score) values('陸小鳳',5,'數學',94); insert into t_variable(name_people, grade, course, score) values('西門吹雪',5,'數學',90); insert into t_variable(name_people, grade, course, score) values('花滿樓',5,'語文',97); insert into t_variable(name_people, grade, course, score) values('陸小鳳',5,'語文',95); insert into t_variable(name_people, grade, course, score) values('西門吹雪',5,'語文',89); insert into t_variable(name_people, grade, course, score) values('花滿樓',5,'科學',93); insert into t_variable(name_people, grade, course, score) values('陸小鳳',5,'科學',96); insert into t_variable(name_people, grade, course, score) values('西門吹雪',5,'科學',94);

2. 變量定義和初始化
- select 新增用戶變量,使用 @var:=value 來進行賦值初始化
select @a:=1 as a, @b:=3 as b;
- set 初始化變量,兩種方式均可:@var:=value 或者 @var=value
set @a=1, @b=3; set @a:=1, @b:=3; select @a as a, @b as b; #先set,再使用
- 下次再打開連接的時候,值就會為Null了,需要重新賦值,即有類似的作用域或生命周期
select @a as a, @b as b; #重新打開連接,未賦值直接使用,會顯示Null
3. 使用變量@:join
select * from t_variable as t1 cross join #直接笛卡爾積 ( select @a:=1 as a, @b:=3 as b ) as t2;

4. 使用變量@:用於判斷和新增列
- 不滿足if條件時:由於 @a!=2,所以 if 語句每次返回第二個值 @b 作為 b_change 的值,且@a本身無變化。
select name_people, course, @a as a, @b as b, if(@a=2, @b:=@b+2, @b) as b_change from ( select * from t_variable as t1 cross join #直接笛卡爾積 ( select @a:=1, @b:=3 ) as t2 ) as t3;

- 滿足if條件時:由於 @a=1,所以 if 語句每次返回第一個值 @b:=@b+2 作為 b_change 的值,且@b在下一條記錄時已經變化,但@a本身無變化。
select name_people, course, @a as a, @b as b, if(@a=1, @b:=@b+2, @b) as b_change from ( select * from t_variable as t1 cross join #直接笛卡爾積 ( select @a:=1, #初始值 @b:=3 ) as t2 ) as t3;

- 滿足if條件,且@a變化:由於 第一次@a=1,所以 if 語句返回第一個值 @b:=@b+2 作為 b_change 的值,且@b在下一條記錄時已經變化;但@a又經過@a:=@a+1,改變了@a的值,所以下一次if條件不能成立了,於是返回的只是@b。
select name_people, course, @a as a, @b as b, if(@a=1, @b:=@b+2, @b) as b_change, #返回值是變量值 @a:=@a+1 as a_change #修改了@a的值,也就是從上往下,每一次返回記錄時都會執行,可用於加入排序值的列 from ( select * from t_variable as t1 cross join #直接笛卡爾積 ( select @a:=1, #初始值 @b:=3 ) as t2 ) as t3;

看到此時的變量a有什么特點:沒錯,就是按序排列的,所以可用於增加排序值。
5. 使用變量@:分組排序 —— 先按分組字段和排序字段進行整體排序,這樣相同選擇字段的記錄就會前后排列;然后返回記錄時,每次比較前后記錄的分組字段,各組分別進行排名(因為此時排序字段已經有序了)。
select name_people, course, score, @ss, @tt, if(@ss=course, @tt:=@tt+1, @tt:=1) as rk, @ss:=course as a_course from ( select * from t_variable order by course, score desc # 先按分組字段course和排序字段score進行整體排序,這樣相同選擇字段的記錄就會前后排列 ) as t1 cross join #直接笛卡爾積 ( select @ss:='', #初始值 @tt:=0 ) as t2;

此時,如果要取其中rk=1的記錄的話,直接在外面加一層select進行篩選即可。
注意!!!:同一次連接中,最好不要用同樣的參數名,因為當參數的類型不同時,很可能會影響下一次的結果。
參考:
