mysql变量赋值:如何强制赋值顺序?

时间:2011-02-07 17:25:15

标签: sql mysql variables

由于mysql是一种声明性语言,我无法找到强制赋值变量顺序的方法。

采取此查询:

SET @v1=0;
SET @v2=0;

SELECT @v1, @v2 
FROM MyTable table 
WHERE (@v1:=@v2) is not null 
  AND (@v2:=2) is not null;

结果是:

@v1 | @v2
---------
 2  |  2

这是因为mysql引擎在@ v1之前解析了@ v2。

如何强制分配顺序才能获得此结果:

@v1 | @v2
---------
 0  |  2

编辑:这与以下问题不同:Variable assignment with mysql

这是一个关于强制分配顺序的问题,而不是为什么结果不是预期的结果。

更新: 当你使用左外连接时,结果也很奇怪:

SET @v1=0;

SELECT @v1
FROM Account other 
LEFT OUTER JOIN SimpleValue f_PC ON f_PC.accountId=other.id AND f_PC.refShortcut='PC'  
WHERE CASE WHEN (other.context='44') THEN (@v1:=@v1+1) ELSE null END
ORDER BY @v1 ASC

在这种情况下,查询返回60个结果,但@ v1值为120。

如果我删除左外连接,则v1值为60.为什么?

3 个答案:

答案 0 :(得分:1)

select语句中,该子句从LEFT变为RIGHT,TOP变为BOTTOM,因此它按预期工作(MS Access使用相同的策略)。但是,在WHERE子句中,所有投注均已关闭,并且选择了最佳过滤器。您可以利用CASE语句需要从左到右评估(保留演示顺序)这一事实来强制它。

WHERE CASE WHEN (@v1:=@v2) is not null THEN (@v2:=2) ELSE (@v2:=2) = 0 END

此力是在任一分支中评估(并将2分配给@ v2),但是对于第一次运行,@ v1:= @ v2返回null,@ v2变为2,将其与0进行整体{{ 1}}。第二次,FALSE@v1 := @v2 [= 2]会产生2((@v2:=2))。

答案 1 :(得分:0)

正如您在其他问题的答案中所解释的那样,没有任何保证能够发挥作用。

在您的特定情况下,将分配移动到查询的SELECT部分​​似乎有效:

SET @v1=0;
SET @v2=0;

SELECT (@v1:=@v2), (@v2:=2) 
FROM DUAL

答案 2 :(得分:0)

关于您的示例。

在WHERE子句中,逻辑操作符中的常量操作可能具有最高优先级。

SET @v1=10;
SET @v2=20;
SELECT @v1, @v2 
FROM dual 
WHERE (@v2:=2) is not NULL AND (@v1:=@v2) is not NULL;
=======
@v1 @v2
2   2

SET @v1=30;
SET @v2=40;
SELECT @v1, @v2
FROM dual 
WHERE (@v1:=@v2) is not NULL AND (@v2:=2) is not NULL;
========
@v1 @v2
2   2

以下示例清楚地证明了这一点。建议不要从左到右执行OR语句。 OR运算符首先执行常量分配操作。

SET @v1=10;
SET @v2=20;
SELECT @v1, @v2 
FROM dual 
WHERE (@v2:=3) is not NULL OR (@v1:=@v2+1) is not NULL;
=========
@v1 @v2
10  3

SET @v1=30;
SET @v2=40;
SELECT @v1, @v2
FROM dual 
WHERE (@v1:=@v2+2) is not NULL OR (@v2:=4) is not NULL;
=========
@v1 @v2
30  4

关于分配运算符和您的问题

  

在这种情况下,查询返回60个结果,但@ v1值为120。   删除左外部联接,v1值为60。为什么?

为查询中使用的数据集的每一行求出WHERE子句中的赋值运算符“:=”! 反之亦然,在SELECT子句中,为结果行计算了赋值运算符,并在JOIN和WHERE子句中对行进行了正面验证。

推荐。尝试在WHERE子句中不要使用赋值运算符“:=”。在SELECT子句中使用赋值运算符。