在sql语句中使用时,会话变量的标准行为是什么.
情况1:
在以下示例中,会话变量的行为与预期一致.
MysqL> set @m1=0,@m2=0,@m3=0; Query OK,0 rows affected (0.00 sec) MysqL> MysqL> select -> @m1 := 55 m1,@m2 := 42 m2,@m3 := 66 m3,-> @m1,@m2,@m3,-> @b1 := greatest( @m1,@m3 ) b1,-> @b2 := ( ( @total := @m1 + @m2 + @m3 ) -> - ( @b1 + least( @m1,@m3 ) )) b2,-> @total total; +----+----+----+------+------+------+------+------+-------+ | m1 | m2 | m3 | @m1 | @m2 | @m3 | b1 | b2 | total | +----+----+----+------+------+------+------+------+-------+ | 55 | 42 | 66 | 55 | 42 | 66 | 66 | 55 | 163 | +----+----+----+------+------+------+------+------+-------+ 1 row in set (0.00 sec) MysqL> MysqL> set @m1=0,0 rows affected (0.00 sec) MysqL> select -> @m1 := m1+3,@m2 := m2+3,@m3 := m3+3,-> @total total -> from -> ( select 55 m1,42 m2,66 m3 union all select 48,63,92 ) marks_list -> ; +-------------+-------------+-------------+------+------+------+------+------+-------+ | @m1 := m1+3 | @m2 := m2+3 | @m3 := m3+3 | @m1 | @m2 | @m3 | b1 | b2 | total | +-------------+-------------+-------------+------+------+------+------+------+-------+ | 58 | 45 | 69 | 58 | 45 | 69 | 69 | 58 | 172 | | 51 | 66 | 95 | 51 | 66 | 95 | 95 | 66 | 212 | +-------------+-------------+-------------+------+------+------+------+------+-------+ 2 rows in set (0.00 sec)
上面的示例没有使用任何聚合函数.
案例2:
当使用count,sum,group by等聚合函数执行类似的语句时,结果模式完全不同.
请查看以下示例:SQL Fiddle
在发布此查询之前,我试图了解SQL-Query-Order-of-Operations.
解决方法
如果我理解正确,您就会询问select语句中表达式的评估顺序. MysqL
documentation很清楚你不能依赖于此:
In the following statement,you
might think that MysqL will evaluate @a first and then do an
assignment second:06000
However,the order of evaluation for expressions involving user
variables is undefined.
我认为问题是您希望按顺序分配值.这是不正确的.也就是说,我必须承认,在使用变量时,我确实做出了相同的顺序评估假设,主要是出于懒惰以及它通常起作用的事实.
如果您想保证顺序评估,请使用案例技巧:
select (case when (@m := 55) is null then null when (@m := 42) is null then null . . . end)
该案例保证了条件的顺序评估,直到一个为真.与null的比较确保了所有得到的评估.