mysql变量赋值:如何强制赋值顺序?
由于mysql是一种声明性语言,我无法找到强制赋值变量顺序的方法 以这个查询为例:mysql变量赋值:如何强制赋值顺序?,sql,mysql,variables,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 ----
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
编辑:这与以下问题不同:
这里有一个关于强制分配顺序的问题,而不是为什么结果不是预期的结果
更新:
使用左外联接时,结果也很奇怪:
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。为什么?正如你在回答另一个问题时所解释的那样,任何东西都不能保证有效 在您的特定情况下,将分配移动到查询的SELECT部分似乎有效:
SET @v1=0;
SET @v2=0;
SELECT (@v1:=@v2), (@v2:=2)
FROM DUAL
在
select
语句中,该子句从左到右、从上到下,因此其结果与预期一致(MS Access使用相同的策略)。然而,在WHERE子句中,所有赌注都被取消,并选择了最佳过滤器。您可以利用CASE语句需要从左到右求值(保留表示顺序)这一事实来强制它
此强制将在任一分支中求值(并将2分配给@v2),但仅在第一次运行时,@v1:=@v2返回null,@v2变为2,与0进行比较,以获得总体
FALSE
。第二次,@v1:=@v2[=2]
,和(@v2:=2)
的结果是2(这是正确的)。关于您的示例。
假设带有常量的操作在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。为什么?
赋值运算符“:=”in WHERE子句是为查询中使用的每一行数据集计算出来的!
反之亦然,在SELECT子句中,为生成的行计算赋值运算符,以肯定地验证JOIN和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
建议。尽量不要在WHERE子句中使用赋值运算符“:=”。在SELECT子句中使用赋值运算符。可能重复您为什么再次问这个问题?这不是同一个问题,另一个问题是为什么我有这些结果?现在的问题是我如何才能取得预期的结果。由于StackOverflow不是一个论坛,我更喜欢打开另一个问题,因为我认为如果我只是编辑和转换这个问题,读过另一个问题的人不会回答它?@jerome-c Fair,感谢您更新此问题。我无法将其移动到select语句,因为我在where子句中使用了变量,select语句中的赋值仅在向客户端发送响应时计算。感谢您的回答,但它不会使用左外部联接运行。查看我的更新;)