有没有可能做这样的事情?
SELECT
@z:=SUM(item),
2*@z
FROM
TableA;
我总是得到第二列的 NULL 。奇怪的是,在做类似的事情时
SELECT
@z:=someProcedure(item),
2*@z
FROM
TableA;
一切都按预期工作。为什么?
有没有可能做这样的事情?
SELECT
@z:=SUM(item),
2*@z
FROM
TableA;
我总是得到第二列的 NULL 。奇怪的是,在做类似的事情时
SELECT
@z:=someProcedure(item),
2*@z
FROM
TableA;
一切都按预期工作。为什么?
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;
适用于 mysql 5.5
select @code:=sum(2), 2*@code
+---------------+---------+
| @code:=sum(2) | 2*@code |
+---------------+---------+
| 2 | 4 |
+---------------+---------+
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
在额外计算之前执行。
我们不能在同一个选择语句中安全地定义和使用变量。最好的方法是不要SET
在SELECT
查询中使用变量。替代查询是
select temp.z,temp.z*2
from (SELECT sum(item) As `z`
FROM TableA
)temp;