我正在尝试在SELECT查询中进行一些计算,使用用户变量来执行此操作。这很好用,直到我开始使用像SUM
这样的函数来从连接表中收集数据。
简化示例:
SET @a = 1;
SELECT @a := SUM(1 + 1) AS sum, @a
结果:
+------+------+ | sum | @a | +------+------+ | 2 | 1 | +------+------+
我希望@a在这里是2。
其他例子:
SELECT @b := SUM(1 + 1) AS sum, @b;
+------+------+ | sum | @b | +------+------+ | 2 | NULL | +------+------+
现在它为NULL,因为在查询之前@b未设置。
似乎该变量不会被SUM函数的结果覆盖。有什么方法可以解决这个问题吗?
答案 0 :(得分:5)
如上所述in the documentation:
作为一般规则,您永远不应将值分配给用户变量并读取同一语句中的值。您可能会得到您期望的结果,但这不能保证。涉及用户变量的表达式的评估顺序是未定义的,可能会根据给定语句中包含的元素进行更改;此外,MySQL服务器版本之间的订单不保证相同。在SELECT @a, @a:=@a+1, ...
中,您可能认为MySQL将首先评估@a
,然后再进行一次分配。但是,更改语句(例如,通过添加GROUP BY
,HAVING
或ORDER BY
子句)可能会导致MySQL选择具有不同评估顺序的执行计划。
到你问题的第二部分。您可以在这样的查询中初始化@variable
(首先评估子查询):
SELECT @b := SUM(1 + 1) AS sum, @b FROM (SELECT @b:=0) b
答案 1 :(得分:1)
与表达评价有关。在您的情况下,您可以使用子查询 -
SET @a = 1;
SELECT sum, @a FROM
(SELECT @a := SUM(1 + 1) AS sum, @a) t
+------+------+
| sum | @a |
+------+------+
| 2 | 2 |
+------+------+
更多信息 - User-Defined Variables。
作为一般规则,您不应该为用户变量赋值 并在同一语句中读取值。你可能会得到 你期望的结果,但这不能保证。的顺序 涉及用户变量的表达式的评估是未定义的 可能会根据给定声明中包含的元素进行更改; 另外,这个顺序不保证是相同的 MySQL服务器的版本。在SELECT @ a,@ a:= @ a + 1,...,你可以 认为MySQL会首先评估@a然后做一个任务 第二。但是,更改语句(例如,通过添加 GROUP BY,HAVING或ORDER BY子句可能导致MySQL选择一个 执行计划具有不同的评估顺序。