27

有没有可能做这样的事情?

SELECT 
    @z:=SUM(item),
    2*@z
FROM
    TableA;

我总是得到第二列的 NULL 。奇怪的是,在做类似的事情时

SELECT 
    @z:=someProcedure(item),
    2*@z
FROM
    TableA;

一切都按预期工作。为什么?

4

4 回答 4

35

MySQL文档对此非常清楚:

作为一般规则,您永远不应为用户变量赋值并在同一语句中读取该值。您可能会得到预期的结果,但这不能保证。涉及用户变量的表达式的求值顺序是未定义的,并且可能会根据给定语句中包含的元素而改变;此外,不保证此顺序在 MySQL 服务器的版本之间是相同的。在 SELECT @a, @a:=@a+1, ... 中,您可能认为 MySQL 会先评估 @a,然后再进行赋值。但是,更改语句(例如,通过添加 GROUP BY、HAVING 或 ORDER BY 子句)可能会导致 MySQL 选择具有不同评估顺序的执行计划。

您可以使用子查询做您想做的事:

select @z, @z*2
from (SELECT @z:=sum(item)
      FROM TableA
     ) t;
于 2013-05-23T13:45:32.833 回答
3

适用于 mysql 5.5

select @code:=sum(2), 2*@code

+---------------+---------+
| @code:=sum(2) | 2*@code |
+---------------+---------+
|             2 |       4 |
+---------------+---------+
于 2014-07-03T10:33:35.540 回答
1
mysql> select @z := sum(5), if(@z := sum(5), 2*@z, 0) ;
+--------------+------------------------------+
| @z := sum(5) | if(@z := sum(5), 2*@z, null) |
+--------------+------------------------------+
|            5 |                           10 |
+--------------+------------------------------+

2*@z我相信在if语句中包装将确保sum在额外计算之前执行。

于 2015-04-17T09:21:48.487 回答
0

我们不能在同一个选择语句中安全地定义和使用变量。最好的方法是不要SETSELECT查询中使用变量。替代查询是

select temp.z,temp.z*2
    from (SELECT sum(item) As `z`
          FROM TableA
         )temp;
于 2021-11-05T14:33:23.953 回答